springboot源碼的探究

1.springboot程序運(yùn)行,
1.第一步:進(jìn)入run方法:
do: new SpringApplication 對(duì)象


屏幕截圖1png.png

第二步:調(diào)用SpringApplication 初始化方法初始化

image.png

圖片的java代碼分別對(duì)應(yīng)下面的1-8
1:給SpringApplication的resourceLoader(資源加載器)賦值
2:判斷入口主程序不能為空(類似參數(shù)的非空判斷)
3:把主來(lái)源(SpringApplication )放到LinkedHashSet集合里面(有序并去重)
4:判斷應(yīng)用啟動(dòng)的類型:
4.1 NONE(應(yīng)用程序不應(yīng)該作為web應(yīng)用程序運(yùn)行,也不應(yīng)該啟動(dòng)嵌入式web服務(wù)器。) 什么都沒(méi)有,正常流程走,不額外的啟動(dòng)web容器
4.2 SERVLET(應(yīng)用程序應(yīng)該作為一個(gè)基于servlet的web應(yīng)用程序運(yùn)行,并且應(yīng)該啟動(dòng)一個(gè)嵌入式servlet web服務(wù)器。) 基于servlet的web程序,需要啟動(dòng)內(nèi)嵌的servletweb容器
4.3 REACTIVE(應(yīng)用程序應(yīng)該作為響應(yīng)式web應(yīng)用程序運(yùn)行,并且應(yīng)該啟動(dòng)嵌入式響應(yīng)式web服務(wù)器。) 基于reactive的web程序


5:調(diào)用getSpringFactoriesInstances方法給SpringApplication的bootstrappers(引導(dǎo)程序)賦值


屏幕截圖3.png

5.1 調(diào)用getClassLoader方法,獲取一個(gè)classloader(第二步的1. 即: 之前給SpringApplication的resourceLoader(資源加載器)賦值。在這里面被調(diào)用了,因?yàn)橹百x值為null,所以這里運(yùn)行g(shù)etClassLoader方法后,會(huì)調(diào)用ClassUtils.getDefaultClassLoader()返回一個(gè)默認(rèn)的ClassLoader)


image.png

5.2 調(diào)用SpringFactoriesLoader.loadFactoryNames方法(該方法會(huì)去從類路徑中所有的META-INF/spring.factories的文件加載所有的類名)獲取類的名稱放到set集合(去重,使用名稱并確保唯一,以防止重復(fù))
image.png

5.3調(diào)用 createSpringFactoriesInstances方法根據(jù)type(type=Bootstrapper.class), parameterTypes, classLoader, args, names參數(shù)創(chuàng)建對(duì)應(yīng)的springfactory實(shí)例。
5.4 調(diào)用AnnotationAwareOrderComparator.sort方法把這些springfactory實(shí)例排序
6.設(shè)置初始化器(Initializer): 調(diào)用getSpringFactoriesInstances方法根據(jù)type(type=ApplicationContextInitializer.class), parameterTypes, classLoader, args, names參數(shù)創(chuàng)建對(duì)應(yīng)的springfactory實(shí)例。(舉一個(gè)ApplicationContextInitializer在META-INF/spring.factories的某個(gè)文件內(nèi)容如下圖)


image.png

由此可得出,我們自定義一個(gè)ApplicationContextInitializer只需要實(shí)現(xiàn)接口,在spring.factories文件中設(shè)置即可。

7.設(shè)置監(jiān)聽(tīng)器(Listener):調(diào)用getSpringFactoriesInstances方法根據(jù)type(type=ApplicationListener.class), parameterTypes, classLoader, args, names參數(shù)創(chuàng)建對(duì)應(yīng)的springfactory實(shí)例。(舉一個(gè)ApplicationListener在META-INF/spring.factories的某個(gè)文件內(nèi)容如下圖)

image.png

8.調(diào)用deduceMainApplicationClass方法給SpringApplication的bootstrappers(主程序類)賦值


image.png

deduceMainApplicationClass方法:會(huì)從調(diào)用RuntimeException().getStackTrace()方法從堆棧跟蹤目前運(yùn)行的方法。然后從拿到的這些stackTrace里面比較是不是有一個(gè)方法叫做main,如果有那么就把該方法對(duì)應(yīng)的stackTrace的類名稱拿到并用 Class.forName得到該class 返回。所以此時(shí)SpringApplication的bootstrappers(主程序類)的賦值會(huì)為com.huaru.springboot.SpringbootApplication。如下圖


image.png

至此new SpringApplication(primarySources)源碼分析完成。

下面分析new SpringApplication(primarySources)調(diào)用.run(args)方法源碼


image.png
?著作權(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ù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者。

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

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