Spring Boot启动流程深度解析:从main()到应用就绪的完整旅程
🌱 Spring Boot启动流程深度解析:从main()到应用就绪的完整旅程
#SpringBoot核心 #启动原理 #自动配置 #源码解析
一、启动流程图解
(1) 启动类执行 → (2) SpringApplication初始化 → (3) 事件驱动模型启动 ↓ ↓
(4) 环境准备 → (5) 应用上下文创建 → (6) Bean加载与自动配置 ↓ ↓
(7) 执行Runners → (8) 内嵌容器启动 → (9) 应用就绪
二、核心阶段分步详解
1. 启动入口:main方法与@SpringBootApplication
@SpringBootApplication
public class MyApp { public static void main(String[] args) { SpringApplication.run(MyApp.class, args); }
}
@SpringBootApplication 三剑客:
@SpringBootConfiguration
:标记配置类@EnableAutoConfiguration
:启用自动配置@ComponentScan
:包扫描注解
2. SpringApplication初始化
关键源码解析:
// SpringApplication.java
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) { return new SpringApplication(primarySources).run(args);
} public SpringApplication(Class<?>... primarySources) { this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); this.webApplicationType = WebApplicationType.deduceFromClasspath(); setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = deduceMainApplicationClass();
}
初始化关键操作:
- 推断应用类型(Servlet/Reactive)
- 加载
META-INF/spring.factories
中的初始化器和监听器 - 识别主配置类
3. 运行阶段:环境准备与上下文创建
3.1 环境准备
- 加载
application.properties/yml
- 激活Profiles(
spring.profiles.active
) - 配置PropertySources(命令行参数 > 系统变量 > 配置文件)
3.2 创建应用上下文
根据应用类型创建不同上下文:
应用类型 | 上下文实现类 |
---|---|
Servlet Web | AnnotationConfigServletWebServerApplicationContext |
Reactive Web | AnnotationConfigReactiveWebServerApplicationContext |
Non-Web | AnnotationConfigApplicationContext |
4. 自动配置黑魔法
核心流程:
1. 加载所有`META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports`
2. 过滤排除项(@EnableAutoConfiguration.exclude)
3. 条件注解过滤(@ConditionalOnClass等)
4. 按@AutoConfigureOrder排序
5. 加载有效配置类
示例自动配置类:
@AutoConfiguration
@ConditionalOnClass(RedisTemplate.class)
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoConfiguration { @Bean public RedisTemplate<?, ?> redisTemplate() { ... }
}
5. 内嵌容器启动(以Tomcat为例)
启动流程:
1. 创建Tomcat实例 → 2. 初始化Connector → 3. 加载ServletContext
4. 启动线程池 → 5. 绑定端口 → 6. 启动完成
关键源码入口:
// TomcatWebServer.java
public void start() throws WebServerException { this.tomcat.start(); this.startAwaitThread();
}
三、启动扩展点实战
1. 自定义Banner
步骤:
- 在
src/main/resources
下创建banner.txt
- 使用在线生成工具设计ASCII艺术字
- 启用彩色输出(需配置
spring.banner.charset=UTF-8
)
2. ApplicationRunner与CommandLineRunner
@Component
@Order(1)
public class MyRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) { System.out.println("应用启动后执行"); }
}
执行顺序:
CommandLineRunner
→ ApplicationRunner
(同Order值下)
3. 自定义事件监听
@Component
public class MyListener implements ApplicationListener<ApplicationReadyEvent> { @Override public void onApplicationEvent(ApplicationReadyEvent event) { System.out.println("应用已就绪"); }
}
四、启动优化技巧
1. 延迟初始化
# application.properties
spring.main.lazy-initialization=true
优点:加快启动速度
缺点:首次请求可能变慢
2. 排除自动配置
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, RedisAutoConfiguration.class
})
3. 日志级别控制
logging.level.root=WARN
logging.level.org.springframework=ERROR
五、启动问题排查指南
1. 常见启动错误
异常类型 | 常见原因 |
---|---|
BeanCurrentlyInCreationException | 循环依赖 |
PortInUseException | 端口被占用 |
NoSuchBeanDefinitionException | 未正确扫描包 |
2. 诊断工具
- 启动日志分析:
--debug
参数输出自动配置报告 - 线程Dump:
jstack <pid> > thread.txt
- 内存分析:
jmap -dump:format=b,file=heap.hprof <pid>
六、Spring Boot启动全景图
[启动类] │ ├─> 初始化SpringApplication │ ├─> 推断Web类型 │ ├─> 加载初始化器/监听器 │ └─> 识别主配置类 │ ├─> 运行阶段 │ ├─> 准备Environment │ ├─> 创建ApplicationContext │ ├─> 刷新上下文(Bean加载、自动配置) │ ├─> 执行Runners │ └─> 启动内嵌容器 │ └─> 发送ApplicationReadyEvent
掌握Spring Boot启动流程,助您从容应对复杂项目初始化问题! 🚀