Spring Boot 應(yīng)用程序啟動(dòng)流程分析

SpringBoot 有兩個(gè)關(guān)鍵元素:

@SpringBootApplication

SpringApplication 以及 run() 方法


SpringApplication 這個(gè)類(lèi)應(yīng)該算是 Spring Boot 框架的“創(chuàng)新”產(chǎn)物了,原始的 Spring 中并沒(méi)有這個(gè)類(lèi),SpringApplication 中封裝了一套 Spring 應(yīng)用的啟動(dòng)流程,然而這對(duì)用戶完全透明,因此我們上手 Spring Boot 時(shí)感覺(jué)很簡(jiǎn)潔、輕量。


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


比如,把我們天天司空見(jiàn)慣的 Spring Boot 應(yīng)用的啟動(dòng)類(lèi)來(lái)拆解一下寫(xiě)出來(lái)就是這樣:

@SpringBootApplicationpublic classCodeSheepApplication{

publicstaticvoidmain( String[] args ){

//SpringApplication.run( CodeSheepApplication.class args ); SpringApplication app = new SpringApplication( CodeSheepApplication.class );

app.setXXX( ... ); // 用戶自定的擴(kuò)展在此 !??! app.run( args );

}

}

這樣一拆解后我們發(fā)現(xiàn),我們也需要先構(gòu)造 SpringApplication 類(lèi)對(duì)象,然后調(diào)用該對(duì)象的 run() 方法。那么接下來(lái)就講講 SpringApplication 的構(gòu)造過(guò)程 以及其 run() 方法的流程,搞清楚了這個(gè),那么也就搞清楚了SpringBoot應(yīng)用是如何運(yùn)行起來(lái)的!


SpringApplication 實(shí)例的初始化

我們對(duì)照代碼來(lái)看:



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

① 推斷應(yīng)用的類(lèi)型:創(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方法的定義類(lèi)



SpringApplication 的run()方法探秘

先看看代碼長(zhǎng)啥樣子:



各個(gè)主要步驟我已經(jīng)標(biāo)注在上圖之中了,除此之外,我也按照自己的理解畫(huà)了一個(gè)流程圖如下所示,可以對(duì)照數(shù)字標(biāo)示看一下:



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


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


2、然后由 SpringApplicationRunListener 來(lái)發(fā)出 starting 消息


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


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


5、創(chuàng)建 ApplicationContext


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


7、由 SpringApplicationRunListener 來(lái)發(fā)出 contextPrepared 消息,告知SpringBoot 應(yīng)用使用的 ApplicationContext 已準(zhǔn)備OK


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


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


10、由 SpringApplicationRunListener 來(lái)發(fā)出 started 消息


11、完成最終的程序的啟動(dòng)


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


至此,全流程結(jié)束!

聲明:本文轉(zhuǎn)載自蛙課網(wǎng)官方網(wǎng)站

想獲取更多資訊、更多視頻、面試題答案,還有各種資源+源碼+工具

就關(guān)注“蛙課網(wǎng)?!惫娞?hào)吧!

還有不定時(shí)福利分享活動(dòng)等你來(lái)參加哦~

公眾號(hào)回復(fù)“活動(dòng)”了解詳情!8月17日截止!

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

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