一、启动流程概述
Spring Boot 的启动入口通常是 main 方法中调用 SpringApplication.run(主类, args)。整个流程分为初始化阶段(创建 SpringApplication 对象)和运行阶段(执行 run 方法)。
二、初始化阶段(创建 SpringApplication 对象)
-
确定 Web 应用类型
通过检查 Classpath 中是否存在特定类(如javax.servlet.Servlet、org.springframework.web.reactive.DispatcherHandler),判断应用类型:Servlet(Spring MVC)、Reactive(WebFlux)或非 Web 应用。 -
加载 ApplicationContextInitializer
利用SpringFactoriesLoader从所有依赖的META-INF/spring.factories文件中读取键为ApplicationContextInitializer的实现类,实例化后存入initializers集合。这些初始化器会在容器刷新前被调用,用于对ApplicationContext进行自定义设置。 -
加载 ApplicationListener
同样通过SpringFactoriesLoader加载ApplicationListener实现类,存入listeners集合,用于监听 Spring Boot 运行过程中的各种事件。 -
推断主启动类
通过分析当前线程的堆栈信息找到启动类,作为主要配置源(通常标注@SpringBootApplication),后续会将其注册为配置类。
三、运行阶段(执行 run 方法)
-
启动计时器
创建StopWatch对象,开始计时,用于最后输出启动耗时。 -
配置 headless 模式
设置系统属性java.awt.headless = true,适用于无显示器、键盘的服务器环境。 -
获取并启动 SpringApplicationRunListener
从spring.factories加载SpringApplicationRunListener(默认EventPublishingRunListener),调用其starting()方法,发布ApplicationStartingEvent。 -
准备 Environment
根据 Web 类型创建对应的Environment(如StandardServletEnvironment)。加载属性源:系统属性、环境变量、配置文件(application.properties/yml)。发布ApplicationEnvironmentPreparedEvent,允许监听器(如ConfigFileApplicationListener)进一步处理配置(如激活 profile、加载外部配置文件)。 -
打印 Banner
根据配置打印 Banner(可自定义或关闭)。 -
创建 ApplicationContext
根据webApplicationType创建对应的ApplicationContext:- Servlet Web:
AnnotationConfigServletWebServerApplicationContext - Reactive Web:
AnnotationConfigReactiveWebServerApplicationContext - 非 Web:
AnnotationConfigApplicationContext
- Servlet Web:
-
准备 ApplicationContext
- 将
Environment设置到 Context。 - 调用所有
ApplicationContextInitializer的initialize方法。 - 发布
ApplicationContextInitializedEvent事件。 - 将主启动类(作为配置类)注册到 Context。
- 将
-
刷新 ApplicationContext
调用AbstractApplicationContext.refresh(),这是 Spring 容器的核心初始化过程:- BeanFactory 准备:设置类加载器、表达式解析器等。
- 执行 BeanFactoryPostProcessor:包括
ConfigurationClassPostProcessor,解析@Configuration、@ComponentScan、@Import、@Bean等,将 BeanDefinition注册到容器。 - 注册 BeanPostProcessor:拦截 Bean 实例化过程,对bean进行增加(如AOP)。
- 初始化 MessageSource、事件广播器等:国际化
onRefresh模板方法:在ServletWebServerApplicationContext中,此方法会创建并启动内嵌 Web 服务器(如 Tomcat、Jetty)。- 注册监听器。
- 实例化非懒加载的单例 Bean。
- 完成刷新,发布
ContextRefreshedEvent。
-
刷新后置处理:finishRefresh
空方法,留给子类扩展。 -
发布 ApplicationReadyEvent
通知监听器应用已启动完成,可以处理请求。 -
返回 ApplicationContext
run方法返回初始化好的ApplicationContext实例。
四、启动流程图
graph TD
A[开始: main方法调用SpringApplication.run] --> B[创建SpringApplication实例]
subgraph 初始化阶段
B --> B1[确定Web应用类型]
B1 --> B2[加载ApplicationContextInitializer]
B2 --> B3[加载ApplicationListener]
B3 --> B4[推断主启动类]
end
B4 --> C[调用run方法]
subgraph 运行阶段
C --> D[启动StopWatch计时器]
D --> E[配置java.awt.headless]
E --> F[获取并启动SpringApplicationRunListeners<br>发布ApplicationStartingEvent]
F --> G[准备Environment<br>加载配置属性]
G --> H[打印Banner]
H --> I[创建ApplicationContext]
I --> J[准备ApplicationContext<br>应用Initializer]
J --> K[刷新Context<br>调用refresh方法]
subgraph refresh方法内部
K --> K1[BeanFactory准备]
K1 --> K2[执行BeanFactoryPostProcessor<br>解析配置类]
K2 --> K3[注册BeanPostProcessor]
K3 --> K4[初始化MessageSource等]
K4 --> K5[onRefresh<br>启动内嵌Web服务器]
K5 --> K6[注册监听器]
K6 --> K7[初始化剩余单例Bean]
K7 --> K8[完成刷新<br>发布ContextRefreshedEvent]
end
K8 --> L[刷新后置处理]
L --> M[发布ApplicationReadyEvent]
M --> N[返回ApplicationContext]
end
N --> O[启动完成]