Spring Boot項(xiàng)目是怎么啟動的

SpringApplication 這個類應(yīng)該算是 Spring Boot 框架 本身的“創(chuàng)新”產(chǎn)物了,因?yàn)樵嫉腟pring框架中并沒有這個類,SpringApplication 里面封裝了一套Spring應(yīng)用的啟動流程,然而這對用戶完全透明,因此我們上手 Spring Boot 時感覺簡潔且輕量。

一般來說默認(rèn)的 SpringApplication 執(zhí)行流程已經(jīng)可以滿足大部分需求,但是 若用戶想干預(yù)這個過程,則可以通過 SpringApplication 在流程某些地方開啟的 擴(kuò)展點(diǎn) 來完成對流程的擴(kuò)展,典型的擴(kuò)展方案那就是使用 set 方法。

我們來舉一個栗子,把我們天天司空見慣的 Spring Boot 應(yīng)用的啟動類來拆解一下寫出來:

@SpringBootApplication
public class CodeSheepApplication {
 public static void main( String[] args ) {
  // SpringApplication.run( CodeSheepApplication.class args ); // 這是傳統(tǒng)Spring Boot應(yīng)用的啟動,一行代碼搞定,內(nèi)部默認(rèn)做了很多事
  SpringApplication app = new SpringApplication( CodeSheepApplication.class );
  app.setXXX( ... ); // 用戶自定的擴(kuò)展在此 ?。。?  app.run( args );
 }
}

這樣一拆解后我們發(fā)現(xiàn),我們也需要先構(gòu)造 SpringApplication 類對象,然后調(diào)用該對象的 run() 方法。

那么接下來就聊聊 SpringApplication 的構(gòu)造過程 以及其 run()方法的流程,搞清楚了這個,那么也就搞清楚了Spring Boot應(yīng)用是如何運(yùn)行起來的了。


SpringApplication實(shí)例的初始化

還是先對照代碼來看:

圖片

四個關(guān)鍵的步驟已標(biāo)注在圖中,分別解釋如下:

① 推斷應(yīng)用的類型:創(chuàng)建的是REACTIVE應(yīng)用、SERVLET應(yīng)用、NONE 三種中的某一種

② 使用SpringFactoriesLoader查找并加載classpath下META-INF/spring.factories文件中所有可用的 ApplicationContextInitializer

③ 使用SpringFactoriesLoader查找并加載classpath下META-INF/spring.factories文件中的所有可用的 ApplicationListener

④ 推斷并設(shè)置main方法的定義類


SpringApplication的run()方法探秘

先看看代碼長啥樣子:

圖片

關(guān)鍵步驟都已經(jīng)用數(shù)字標(biāo)注在上圖之中了,除此之外,這里也畫了一個流程圖對照理解:

我們將各步驟總結(jié)精煉如下:

  1. 通過 SpringFactoriesLoader 加載 META-INF/spring.factories 文件,獲取并創(chuàng)建 SpringApplicationRunListener 對象

  2. 然后由 SpringApplicationRunListener 來發(fā)出 starting 消息

  3. 創(chuàng)建參數(shù),并配置當(dāng)前 SpringBoot 應(yīng)用將要使用的 Environment

  4. 完成之后,依然由 SpringApplicationRunListener 來發(fā)出 environmentPrepared 消息

  5. 創(chuàng)建 ApplicationContext

  6. 初始化 ApplicationContext,并設(shè)置 Environment,加載相關(guān)配置等

  7. SpringApplicationRunListener 來發(fā)出 contextPrepared 消息,告知Spring Boot 應(yīng)用使用的 ApplicationContext 已準(zhǔn)備OK

  8. 將各種 beans 裝載入 ApplicationContext,繼續(xù)由 SpringApplicationRunListener 來發(fā)出 contextLoaded 消息,告知 Spring Boot 應(yīng)用使用的 ApplicationContext 已裝填OK

  9. refresh ApplicationContext,完成IoC容器可用的最后一步

  10. SpringApplicationRunListener 來發(fā)出 started 消息

  11. 調(diào)用callRunners(...)方法,讓實(shí)現(xiàn)了ApplicationRunnerCommandLineRunner接口類的run 方法得以執(zhí)行,用于在 Spring 應(yīng)用上下文準(zhǔn)備完畢后,執(zhí)行一些額外操作。從而完成最終的程序的啟動。

  12. SpringApplicationRunListener 來發(fā)出 running 消息,告知程序已運(yùn)行起來了

轉(zhuǎn)載:
https://mp.weixin.qq.com/s/T9o2MAwKX9KHS6TkRdYEog

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容