一文彻底弄懂Spring Boot的启动过程

一,Spring Boot启动过程

1. 启动入口

Spring Boot 应用的启动入口通常是一个包含 @SpringBootApplication 注解的主类,并调用 SpringApplication.run() 方法。@SpringBootApplication 是一个复合注解,包含了 @Configuration、@EnableAutoConfiguration 和 @ComponentScan,从而开启了自动配置和组件扫描。

源码路径在 SpringApplication 类的 run() 方法:

public static ConfigurableApplicationContext run(Class primarySource, String... args) {

return new SpringApplication(primarySource).run(args);

}

这个入口主要做了以下几件事情:

创建 SpringApplication 实例:初始化 Spring Boot 环境。

初始化环境和监听器:设置启动的 Environment,并且添加 ApplicationListener 监听器。

准备和刷新 Spring 上下文:通过 prepareContext 和 refreshContext 方法进行上下文环境的准备和刷新。

2. 创建 SpringApplication 实例

在 SpringApplication 的构造方法中,Spring Boot 解析应用的启动模式(例如是 Web 应用、Servlet 应用或是普通应用),并初始化应用的上下文类型。Spring Boot 的不同上下文类型包括 AnnotationConfigApplicationContext(非 Web 应用)和 AnnotationConfigServletWebServerApplicationContext(Web 应用)。

3. 初始化 Environment 和监听器

接下来,Spring Boot 会初始化 ConfigurableEnvironment,这个环境中包含了系统的属性、环境变量、配置文件等数据,作为后续加载 Bean 定义和初始化的基础。

同时,Spring Boot 也会初始化一系列的 ApplicationListener,用于监听和处理应用启动过程中的事件,比如 ApplicationEnvironmentPreparedEvent、ApplicationPreparedEvent 等。

4. 加载配置类并触发自动配置

Spring Boot 使用 @EnableAutoConfiguration 注解触发自动配置,核心实现是在 AutoConfigurationImportSelector 中加载 META-INF/spring.factories 配置文件,文件中列出了许多自动配置类(如 DataSourceAutoConfiguration、JpaRepositoriesAutoConfiguration 等),根据条件(例如某些 Bean 是否存在、某些属性是否被配置等)加载相应的自动配置。

5. 加载并注册 Bean

在 refreshContext() 方法中,Spring Boot 调用 refresh() 方法,这一步骤中完成了 BeanFactory 的初始化和 BeanPostProcessor 的注册,并解析 @Component、@Service、@Repository 等注解标注的 Bean 定义,将它们注册到 BeanFactory 中。

在源码层面,refresh() 方法中,invokeBeanFactoryPostProcessors 和 registerBeanPostProcessors 这两个方法是关键,分别用于执行所有 BeanFactoryPostProcessor 和 BeanPostProcessor,确保 Bean 的生命周期正确管理。

6. Web 环境中的嵌入式容器启动

在 Web 应用中,Spring Boot 会启动嵌入式 Web 容器(如 Tomcat 或 Jetty)。Spring Boot 默认通过 ServletWebServerApplicationContext 启动内嵌的 Web 服务器。在 refresh() 的最后,会启动嵌入式容器,将应用作为 Web 应用发布。

7. 执行 ApplicationRunner 和 CommandLineRunner

Spring Boot 启动完成后,会扫描并执行所有实现了 ApplicationRunner 和 CommandLineRunner 接口的 Bean。它们可以用于在启动后执行自定义逻辑。

8. 发布应用启动完成事件

最后,Spring Boot 发布 ApplicationReadyEvent 事件,通知所有监听器应用已启动完成。至此,Spring Boot 应用正式启动完成,可以接收 HTTP 请求或执行其他任务。

二、Spring Boot 启动过程的架构设计

在 Spring Boot 应用启动的过程中,SpringApplication.run() 是最常用的启动方式。通过这个方法,Spring Boot 为开发者屏蔽了大量复杂的初始化细节,我们只需提供主启动类的入口和简单的配置信息即可启动整个应用。

下面我们从源码入手,分步骤分析 SpringApplication.run 进行的操作。

1,SpringApplication.run() 的详细流程

SpringApplication.run 主要完成以下几大步骤:

初始化 SpringApplication 实例:

该实例负责整个 Spring Boot 应用的启动过程,通过判断应用类型和设置环境变量为后续配置加载和应用上下文创建提供基础。核心方法为 SpringApplication#prepareEnvironment 和 SpringApplication#createApplicationContext。

创建应用上下文并刷新上下文:

SpringApplication 将根据应用类型来创建不同的 ApplicationContext(如 AnnotationConfigApplicationContext 或 ServletWebServerApplicationContext),并将所有 Bean 装载到上下文中。

加载环境配置:

Spring Boot 会基于开发环境或生产环境加载不同的配置文件。核心是 ConfigFileApplicationListener 监听配置事件,解析应用配置文件(application.properties 或 application.yml)并装配到应用上下文的 Environment 对象中。

启动嵌入式容器:

如果是 Web 应用,Spring Boot 会启动内嵌的服务器(如 Tomcat、Jetty 或 Undertow),并将 DispatcherServlet 注册到服务器中。

https://www.cnblogs.com/lgx211/p/18535984