生活随笔
收集整理的這篇文章主要介紹了
SpringApplication.run做了哪些事情
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
URL
https://mp.weixin.qq.com/s/uP4seo__qYMJMzmbWyUUnA?tdsourcetag=s_pctim_aiomsg
SpringApplication.run
- 總共做了兩件事情,如下源碼
- 穿件SpringApplication對象
- 利用創建好的對象調用run方法
public static ConfigurableApplicationContext
run(Object source
, String
... args
) {return run(new Object[] { source
}, args
);}
public static ConfigurableApplicationContext
run(Object
[] sources
, String
[] args
) {return new SpringApplication(sources
).run(args
);}
- 此處開始分成兩個部分,一部分:SpringApplication(sources)進行SpringApplication的初始化工作,包括各種配置的初始化,listener初始化等 二部分:run(args)執行run方法啟動
public SpringApplication(Object
... sources
) {initialize(sources
);}
private void initialize(Object
[] sources
) {if (sources
!= null
&& sources
.length
> 0) {this.sources
.addAll(Arrays
.asList(sources
));}this.webEnvironment
= deduceWebEnvironment();setInitializers((Collection
) getSpringFactoriesInstances(ApplicationContextInitializer
.class));setListeners((Collection
) getSpringFactoriesInstances(ApplicationListener
.class));this.mainApplicationClass
= deduceMainApplicationClass();}
private Class
<?> deduceMainApplicationClass() {try {StackTraceElement
[] stackTrace
= new RuntimeException().getStackTrace();for (StackTraceElement stackTraceElement
: stackTrace
) {if ("main".equals(stackTraceElement
.getMethodName())) {return Class
.forName(stackTraceElement
.getClassName());}}}catch (ClassNotFoundException ex
) {}return null
;}
- 在初始化步驟中
- 步驟1 保存主配置信息
- 步驟2 判斷當前是否是web應用
- 步驟3中可以看到方法getSpringFactoriesInstances作用在于通過到路徑META_INF/spring.factories配置中所有ApplicationContextinitializer配置信息的list,接著通過initializers 將配置信息保存
- 步驟4 中同步驟3 一致,只不過這次獲取的配置類型不同,連調用的方法都是一樣的,這次獲取的是ApplicationListener類型的配置,之后保存
- 步驟5 中的deduceMainApplicationClass 方法在尋址一個包含main方法的配置類,如上部分代碼,也就是我們自己寫的啟動類
- 第二部分則是運行對應的run方法:
public ConfigurableApplicationContext
run(String
... args
) {StopWatch stopWatch
= new StopWatch();stopWatch
.start();ConfigurableApplicationContext context
= null
;FailureAnalyzers analyzers
= null
;configureHeadlessProperty();SpringApplicationRunListeners listeners
= getRunListeners(args
);listeners
.starting();try {ApplicationArguments applicationArguments
= new DefaultApplicationArguments(args
);ConfigurableEnvironment environment
= prepareEnvironment(listeners
,applicationArguments
);Banner printedBanner
= printBanner(environment
);context
= createApplicationContext();analyzers
= new FailureAnalyzers(context
);prepareContext(context
, environment
, listeners
, applicationArguments
,printedBanner
);refreshContext(context
);afterRefresh(context
, applicationArguments
);listeners
.finished(context
, null
);stopWatch
.stop();if (this.logStartupInfo
) {new StartupInfoLogger(this.mainApplicationClass
).logStarted(getApplicationLog(), stopWatch
);}return context
;}catch (Throwable ex
) {handleRunFailure(context
, listeners
, analyzers
, ex
);throw new IllegalStateException(ex
);}}
private ConfigurableEnvironment
prepareEnvironment(SpringApplicationRunListeners listeners
,ApplicationArguments applicationArguments
) {ConfigurableEnvironment environment
= getOrCreateEnvironment();configureEnvironment(environment
, applicationArguments
.getSourceArgs());listeners
.environmentPrepared(environment
);if (!this.webEnvironment
) {environment
= new EnvironmentConverter(getClassLoader()).convertToStandardEnvironmentIfNecessary(environment
);}return environment
;}
此處先調用getRunListeners方法,同之前一樣,是獲取META_INF/Spring.factories文件中的配置信息,配置信息類型是:SpringApplicationRunListeners在得到對應的配置信息后,調用gstarting方法,改方法會去循環調用剛才獲取到的所有配置,并且觸發SpringApplicationRunListener中的starting事件,并且是異步的形式觸發接著封裝我們的命令行參數,也就是我們main方法中傳入的args參數封裝成對應的ApplicationArguments,此處步驟會先準備對應環境,主要是我們在配置的配置信息的駕照,在完成環境準備之后在listeners.environmentPrepared(environment); 方法中會回調SpringApplicationRunListener中的environmentPrepared 事件,也是同樣的異步的方式觸發這個步驟pringBanner,啟動時候banner的打印,可以自定義自步驟中的圖形createApplicationContext方法會更具我們之前環境判斷信來是web環境還是其他決定創建web還是普通的IOC容器此步驟中有多個功能 將environment上下文環境信息保存早ioc容器中執行applyInitializers 方法,改方法會遍歷之前保存的ApplicationContextInitializer的initialize()事件在contextPerpared中遍歷SpringApplicationRunListener中的ContextPrepared()事件最后在contextLoaded方法中回調SpringApplicationRunListener中的ContextLoaded()事件 refreshContext顧名思義,刷新容器,進行組件的掃描創建,加載等afterRefresh從IOC容器中獲取所有ApplicationRunner和CommandLineRunner遍歷所有runner并且調用callRunner方法回調用,先調用ApplicationRunner,在調用CommandLineRunnerfinished方法中遍歷SpringApplicationRunListener中的finished()事件最后返回context ioc容器
總結
- SpringApplication.run一共做了兩件事,一件是創建SpringApplication對象,在該對象初始化時,找到配置的事件監聽器,并保存起來.第二件事就是運行run方法,此時會將剛才保存的事件監聽器根據當前時機觸發不同的事件,比如容器初始化,容器創建完成等.同時也會刷新IoC容器,進行組件的掃描、創建、加載等工作.
總結
以上是生活随笔為你收集整理的SpringApplication.run做了哪些事情的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。