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應用能夠快速、便捷地運行起來。