84、原理解析-SpringApplication初始化流程
# SpringApplication创建初始化流程原理解析
`SpringApplication`的创建和初始化是Spring Boot应用启动的关键步骤,主要包括以下过程:
## 1. 创建SpringApplication实例
### 1.1 调用构造函数
- 当调用`SpringApplication.run()`方法时,会先创建`SpringApplication`实例。
- 构造函数接受主配置类(通常标有`@SpringBootApplication`注解的类)作为参数。
### 1.2 设置基本属性
- **ResourceLoader**:设置资源加载器,默认为`null`,后续会根据需要自动设置。
- **PrimarySources**:将传入的主配置类保存到`primarySources`集合中。
- **MainApplicationClass**:推断并保存启动应用的主类,用于后续反射调用。
## 2. 推断Web应用类型
### 2.1 类路径检测
- 通过`WebApplicationType.deduceFromClasspath()`方法,根据类路径中是否存在特定类来判断应用类型:
- **REACTIVE**:存在`org.springframework.web.reactive.DispatcherHandler`且不存在`org.springframework.web.servlet.DispatcherServlet`。
- **SERVLET**:存在`javax.servlet.Servlet`和`org.springframework.web.servlet.DispatcherServlet`。
- **NONE**:不满足以上条件,为非Web应用。
## 3. 加载初始化器和监听器
### 3.1 加载`ApplicationContextInitializer`
- 从`META-INF/spring.factories`文件中获取并实例化所有`ApplicationContextInitializer`的实现类。
- 这些初始化器在上下文刷新前执行,可用于对应用上下文进行自定义配置。
### 3.2 加载`ApplicationListener`
- 从`META-INF/spring.factories`文件中获取并实例化所有`ApplicationListener`的实现类。
- 这些监听器用于监听Spring应用生命周期中的事件,如应用启动、上下文刷新等。
## 4. 设置引导上下文(Bootstrap Context)
- 创建`BootstrapContext`,用于在应用上下文初始化之前执行一些引导操作。
- 加载`BootstrapRegistryInitializer`,用于初始化引导注册表,提供早期访问配置和环境信息的能力。
## 5. 环境准备
### 5.1 配置环境
- 创建并配置应用环境(`ConfigurableEnvironment`),包括系统属性、环境变量、命令行参数等。
- 根据应用类型和环境信息,创建相应的环境对象,如`StandardServletEnvironment`或`StandardReactiveWebEnvironment`。
### 5.2 配置属性源
- 将命令行参数、配置文件等属性源添加到环境中,确保应用可以访问这些配置信息。
## 6. 创建应用上下文
### 6.1 创建上下文实例
- 根据推断的应用类型,创建相应的应用上下文:
- **SERVLET**:创建`AnnotationConfigServletWebServerApplicationContext`。
- **REACTIVE**:创建`AnnotationConfigReactiveWebServerApplicationContext`。
- **NONE**:创建`AnnotationConfigApplicationContext`。
### 6.2 准备上下文
- 将初始化器、监听器、环境等配置应用到上下文。
- 调用`prepareContext()`方法,执行上下文初始化前的准备工作。
## 7. 刷新应用上下文
### 7.1 加载Bean定义
- 扫描并加载所有配置类中的Bean定义,包括组件扫描、导入的配置文件等。
### 7.2 实例化Bean
- 根据Bean定义,实例化并初始化所有单例Bean。
### 7.3 触发事件
- 发布上下文刷新事件(`ContextRefreshedEvent`),通知所有监听器上下文已刷新。
## 8. 启动嵌入式Web服务器(可选)
- 如果是Web应用,启动嵌入式的Tomcat、Jetty或Undertow服务器。
- 将应用部署到服务器上,开始监听请求。
## 9. 完成启动
- 打印启动日志,显示应用启动成功的信息。
- 应用进入运行状态,开始处理请求或执行业务逻辑。
---
通过上述流程,`SpringApplication`完成了应用的创建、初始化和启动,使Spring Boot应用能够快速、便捷地运行起来。