Spring Boot 的启动流程是一个高度封装但逻辑清晰的过程,核心目标是将 Spring 应用上下文(ApplicationContext
)初始化并启动,最终使应用进入就绪状态。以下是 Spring Boot 启动流程的详细解析,按阶段划分并说明关键步骤和核心类。
一、启动入口:main
方法与 SpringApplication.run()
Spring Boot 应用的启动通常从 main
方法开始,用户通过调用 SpringApplication.run(Class<?> primarySource, String... args)
启动应用。这是启动流程的起点。
关键代码片段:
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args); // 启动入口
}
}
执行逻辑:
-
创建
SpringApplication
实例:
SpringApplication.run()
方法内部会创建SpringApplication
对象,传入主配置类(如MyApp.class
)和命令行参数args
。
SpringApplication
是启动流程的核心协调类,负责初始化环境、上下文和启动应用。 -
调用
run
方法:
SpringApplication
的run
方法是启动流程的总控制器,负责执行以下核心步骤:- 准备环境(
Environment
) - 创建并刷新应用上下文(
ApplicationContext
) - 发布启动完成事件(
ApplicationReadyEvent
)
- 准备环境(
二、阶段一:初始化 SpringApplication
SpringApplication
构造时完成以下关键初始化:
1. 确定应用类型(Application Type)
根据类路径中的依赖(如 spring-boot-starter-web
)判断应用类型(WebApplicationType
):
NONE
:无 Web 支持(普通 Spring 应用)。SERVLET
:基于 Servlet 的 Web 应用(如 Spring MVC)。REACTIVE
:基于 Reactive 的 Web 应用(如 Spring WebFlux)。
示例:若类路径中存在 DispatcherServlet
,则应用类型为 SERVLET
。
2. 收集初始配置(Initializers and Listeners)
ApplicationContextInitializer
:从META-INF/spring.factories
中加载所有ApplicationContextInitializer
实现类(如ContextIdApplicationContextInitializer
),用于初始化上下文。ApplicationListener
:加载所有ApplicationListener
实现类(如LoggingApplicationListener
),用于监听启动事件。
这些配置类会在后续阶段被调用,参与上下文初始化或事件处理。
3. 确定主配置类(Primary Source)
主配置类(如 MyApp.class
)是用户标记了 @SpringBootApplication
的类,SpringApplication
会将其作为配置源之一,用于扫描 @Component
、@Configuration
等注解。
三、阶段二:准备环境(Environment)
环境(Environment
)是 Spring 应用的配置中心,存储了系统属性、环境变量、配置文件(如 application.properties
)等键值对。SpringApplication
在创建上下文前会初始化环境。
关键步骤:
-
创建
Environment
对象:
根据应用类型创建对应的Environment
(如StandardServletEnvironment
用于 Web 应用),默认包含systemProperties
和systemEnvironment
作为属性源。 -
加载配置文件:
- 从类路径、文件系统等位置加载
application.properties
、application.yml
等配置文件。 - 支持
@PropertySource
注解显式指定配置文件。
- 从类路径、文件系统等位置加载
-
处理命令行参数:
将命令行参数(如--server.port=8081
)添加到环境中,覆盖配置文件中的同名属性。 -
触发
ApplicationEnvironmentPreparedEvent
:
环境准备完成后,SpringApplication
发布ApplicationEnvironmentPreparedEvent
事件,通知监听器环境已就绪(如日志系统可在此阶段初始化)。
四、阶段三:创建并刷新应用上下文(ApplicationContext)
应用上下文(ApplicationContext
)是 Spring 容器的核心,负责管理 Bean 的生命周期、依赖注入和配置。SpringApplication
会根据应用类型创建对应的上下文实现类:
应用类型 | 上下文实现类 | 说明 |
---|---|---|
普通 Spring 应用 | AnnotationConfigApplicationContext | 基于注解的普通容器。 |
Servlet Web 应用 | AnnotationConfigServletWebServerApplicationContext | 支持 Servlet 规范,包含 WebServer (如 Tomcat)。 |
Reactive Web 应用 | AnnotationConfigReactiveWebServerApplicationContext | 支持 Reactive 规范(如 WebFlux)。 |
关键步骤:刷新上下文(refresh()
方法)
ApplicationContext
的 refresh()
方法是容器启动的核心,包含以下子步骤(简化流程):
-
准备刷新(Prepare Refresh):
- 标记上下文为“正在刷新”状态。
- 初始化
BeanFactory
(核心容器,存储BeanDefinition
和Bean
实例)。
-
处理配置类(Process Configuration Classes):
- 扫描主配置类及其依赖的配置类(通过
@ComponentScan
或@Import
)。 - 解析
@Bean
、@ImportResource
、@PropertySource
等注解,生成BeanDefinition
并注册到BeanFactory
。
- 扫描主配置类及其依赖的配置类(通过
-
初始化
BeanFactoryPostProcessor
:
调用所有BeanFactoryPostProcessor
实现类(如ConfigurationClassPostProcessor
),允许自定义修改BeanDefinition
(如动态注册 Bean)。 -
初始化
BeanPostProcessor
:
注册BeanPostProcessor
实现类(如AutowiredAnnotationBeanPostProcessor
、CommonAnnotationBeanPostProcessor
),用于处理 Bean 的依赖注入和生命周期回调。 -
初始化消息源(Message Source):
初始化MessageSource
(如ReloadableResourceBundleMessageSource
),用于国际化消息解析。 -
初始化应用事件多播器(Application Event Multicaster):
初始化ApplicationEventMulticaster
(如SimpleApplicationEventMulticaster
),用于事件的发布和监听。 -
注册监听器(Register Listeners):
将ApplicationListener
实现类注册到事件多播器,以便接收后续事件。 -
初始化所有单例 Bean(Finish Bean Initialization):
调用BeanFactory
的preInstantiateSingletons()
方法,实例化并初始化所有单例 Bean(通过getBean()
触发)。- 对于
@Autowired
、@Resource
注解的依赖,通过AutowiredAnnotationBeanPostProcessor
完成注入。 - 对于
InitializingBean
、@PostConstruct
注解的 Bean,调用初始化方法。
- 对于
-
完成刷新(Finish Refresh):
- 标记上下文为“已刷新”状态。
- 启动
WebServer
(如 Tomcat),使 Web 应用进入就绪状态。
五、阶段四:发布启动完成事件(ApplicationReadyEvent
)
上下文刷新完成后,SpringApplication
发布 ApplicationReadyEvent
事件,通知所有监听器应用已启动完成。此时:
- Web 应用的
DispatcherServlet
已初始化,可处理 HTTP 请求。 - 自定义的
ApplicationListener
可在此阶段执行启动后逻辑(如健康检查、定时任务启动)。
六、关键类与扩展点总结
Spring Boot 启动流程涉及多个核心类和扩展点,理解它们的协作关系有助于定位问题和自定义启动逻辑:
核心类/接口 | 作用 |
---|---|
SpringApplication | 启动流程的总控制器,负责环境准备、上下文创建和事件发布。 |
ApplicationContext | Spring 容器核心,管理 Bean 的生命周期和依赖注入(如 AnnotationConfigServletWebServerApplicationContext )。 |
Environment | 配置中心,存储系统属性、环境变量、配置文件等键值对。 |
BeanFactoryPostProcessor | 允许自定义修改 BeanDefinition (如动态注册 Bean)。 |
BeanPostProcessor | 处理 Bean 的依赖注入(如 @Autowired )和生命周期回调(如 @PostConstruct )。 |
ApplicationListener | 监听启动事件(如 ApplicationEnvironmentPreparedEvent 、ApplicationReadyEvent )。 |
七、总结
Spring Boot 的启动流程可概括为:
main
方法 → SpringApplication
初始化 → 环境准备 → 上下文创建与刷新 → 发布启动完成事件。
每个阶段均有明确的职责和扩展点,开发者可通过自定义 ApplicationContextInitializer
、BeanFactoryPostProcessor
或监听事件来干预启动流程,满足个性化需求。理解这一流程有助于深入掌握 Spring Boot 的核心机制,提升问题排查和定制开发能力。