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

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

圖片的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)程序)賦值

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)

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

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)容如下圖)

由此可得出,我們自定義一個(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)容如下圖)

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

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。如下圖

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