一文彻底弄懂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