Spring Boot 的启动流程是一个复杂且有序的过程:
创建SpringApplication实例 --- 调用run方法 --- 启动完成(发布应用启动事件,配置环境,创建ApplicationContext,准备ApplicationContext,刷新ApplicationContext[【创建BeanFactory,加载Bean定义,创建Bean实例,启动嵌入式服务器】,发布应用就绪事件) --- 异常处理;
下面将详细拆解其各个阶段。
1. 启动入口
Spring Boot 应用的启动通常从一个带有 @SpringBootApplication
注解的主类的 main
方法开始。@SpringBootApplication
是一个组合注解,包含了 @Configuration
、@EnableAutoConfiguration
和 @ComponentScan
,分别用于配置类、启用自动配置和组件扫描。
java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}
2. 创建 SpringApplication
实例
在调用 SpringApplication.run
方法时,首先会创建一个 SpringApplication
实例。这个实例负责配置和启动 Spring Boot 应用。在创建过程中,会进行以下操作:
- 推断应用类型:判断应用是普通的 Servlet 应用、Reactive 应用还是其他类型。
- 查找并加载初始化器(
ApplicationContextInitializer
) :初始化器可以在ApplicationContext
创建之前对其进行自定义配置。 - 查找并加载监听器(
ApplicationListener
):监听器用于监听应用启动过程中的各种事件,如应用启动、失败等。 - 推断主类 :确定包含
main
方法的主类。
3. 调用 run
方法
SpringApplication
实例创建完成后,会调用其 run
方法,该方法包含了一系列关键步骤。
3.1 发布应用启动事件(ApplicationStartingEvent
)
当 run
方法开始执行时,会发布 ApplicationStartingEvent
事件,通知所有注册的监听器应用正在启动。
3.2 配置环境(ConfigurableEnvironment
)
- 创建环境对象 :根据应用类型创建相应的环境对象,如
StandardServletEnvironment
或StandardReactiveEnvironment
。 - 加载属性源:从各种属性源(如配置文件、系统属性、环境变量等)加载配置属性。
- 发布环境准备好事件(
ApplicationEnvironmentPreparedEvent
):通知监听器环境已经准备好。
3.3 创建 ApplicationContext
根据应用类型创建相应的 ApplicationContext
实例,如 AnnotationConfigServletWebServerApplicationContext
用于 Servlet 应用,AnnotationConfigReactiveWebServerApplicationContext
用于 Reactive 应用。
3.4 准备 ApplicationContext
- 设置环境 :将之前配置好的环境对象设置到
ApplicationContext
中。 - 应用初始化器 :调用之前加载的初始化器对
ApplicationContext
进行自定义配置。 - 发布上下文准备好事件(
ApplicationContextInitializedEvent
):通知监听器上下文已经初始化。 - 加载 Bean 定义:扫描并加载应用中的 Bean 定义。
3.5 刷新 ApplicationContext
调用 ApplicationContext
的 refresh
方法,这是 Spring 框架的核心方法,会完成以下重要操作:
- 创建 BeanFactory :创建
DefaultListableBeanFactory
用于管理 Bean 的创建和依赖注入。 - 加载 Bean 定义 :将之前扫描到的 Bean 定义注册到
BeanFactory
中。 - 创建 Bean 实例:根据 Bean 的定义创建 Bean 实例,并进行属性注入和初始化。
- 启动嵌入式服务器(如果是 Web 应用):如 Tomcat、Jetty 等,用于处理 HTTP 请求。
3.6 发布应用就绪事件(ApplicationReadyEvent
)
当 ApplicationContext
刷新完成且嵌入式服务器启动成功后,会发布 ApplicationReadyEvent
事件,通知监听器应用已经准备好接受请求。
3.7 调用 CommandLineRunner
和 ApplicationRunner
如果应用中定义了实现 CommandLineRunner
或 ApplicationRunner
接口的 Bean,会依次调用它们的 run
方法,允许开发者在应用启动后执行一些自定义逻辑。
4. 启动完成
当上述步骤都执行完毕后,Spring Boot 应用启动完成,开始监听客户端请求,提供服务。
5. 异常处理
在整个启动过程中,如果发生异常,会发布 ApplicationFailedEvent
事件,通知监听器应用启动失败,并打印详细的错误信息。
综上所述,Spring Boot 的启动流程涉及多个阶段和事件,通过事件机制和各种扩展点,开发者可以在不同阶段对应用进行自定义配置和扩展。