日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

SpringApplication.run做了哪些事情

發(fā)布時(shí)間:2023/12/4 javascript 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringApplication.run做了哪些事情 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
URL

https://mp.weixin.qq.com/s/uP4seo__qYMJMzmbWyUUnA?tdsourcetag=s_pctim_aiomsg

SpringApplication.run
  • 總共做了兩件事情,如下源碼
    • 穿件SpringApplication對(duì)象
    • 利用創(chuàng)建好的對(duì)象調(diào)用run方法
// SpringApplication.run(Application.class, args);進(jìn)入 --- 1 public static ConfigurableApplicationContext run(Object source, String... args) {return run(new Object[] { source }, args);}//以上run 方法進(jìn)去 public static ConfigurableApplicationContext run(Object[] sources, String[] args) {return new SpringApplication(sources).run(args);}
  • 此處開(kāi)始分成兩個(gè)部分,一部分:SpringApplication(sources)進(jìn)行SpringApplication的初始化工作,包括各種配置的初始化,listener初始化等 二部分:run(args)執(zhí)行run方法啟動(dòng)
//初始化開(kāi)始 public SpringApplication(Object... sources) {initialize(sources);} //initialize 方法 private void initialize(Object[] sources) {if (sources != null && sources.length > 0) {// ------1this.sources.addAll(Arrays.asList(sources));}// ----------2this.webEnvironment = deduceWebEnvironment();//--------3setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));//-----------4setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));//----------5this.mainApplicationClass = deduceMainApplicationClass();}//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) {// Swallow and continue}return null;}
  • 在初始化步驟中
    • 步驟1 保存主配置信息
    • 步驟2 判斷當(dāng)前是否是web應(yīng)用
    • 步驟3中可以看到方法getSpringFactoriesInstances作用在于通過(guò)到路徑META_INF/spring.factories配置中所有ApplicationContextinitializer配置信息的list,接著通過(guò)initializers 將配置信息保存
    • 步驟4 中同步驟3 一致,只不過(guò)這次獲取的配置類(lèi)型不同,連調(diào)用的方法都是一樣的,這次獲取的是ApplicationListener類(lèi)型的配置,之后保存
    • 步驟5 中的deduceMainApplicationClass 方法在尋址一個(gè)包含main方法的配置類(lèi),如上部分代碼,也就是我們自己寫(xiě)的啟動(dòng)類(lèi)
  • 第二部分則是運(yùn)行對(duì)應(yīng)的run方法:
public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;FailureAnalyzers analyzers = null;configureHeadlessProperty();//-----------1SpringApplicationRunListeners listeners = getRunListeners(args);//-----------2listeners.starting();try {//----------3ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);// ----------4ConfigurableEnvironment environment = prepareEnvironment(listeners,applicationArguments);//--------5Banner printedBanner = printBanner(environment);//----------6context = createApplicationContext();analyzers = new FailureAnalyzers(context);//---7prepareContext(context, environment, listeners, applicationArguments,printedBanner);//---8refreshContext(context);// -----------9afterRefresh(context, applicationArguments);//--------10listeners.finished(context, null);stopWatch.stop();if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}// --------11return context;}catch (Throwable ex) {handleRunFailure(context, listeners, analyzers, ex);throw new IllegalStateException(ex);}}// 4步驟中流程: private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments) {// Create and configure the environmentConfigurableEnvironment environment = getOrCreateEnvironment();configureEnvironment(environment, applicationArguments.getSourceArgs());listeners.environmentPrepared(environment);if (!this.webEnvironment) {environment = new EnvironmentConverter(getClassLoader()).convertToStandardEnvironmentIfNecessary(environment);}return environment;}
  • run方法解析:
  • 此處先調(diào)用getRunListeners方法,同之前一樣,是獲取META_INF/Spring.factories文件中的配置信息,配置信息類(lèi)型是:SpringApplicationRunListeners
  • 在得到對(duì)應(yīng)的配置信息后,調(diào)用gstarting方法,改方法會(huì)去循環(huán)調(diào)用剛才獲取到的所有配置,并且觸發(fā)SpringApplicationRunListener中的starting事件,并且是異步的形式觸發(fā)
  • 接著封裝我們的命令行參數(shù),也就是我們main方法中傳入的args參數(shù)封裝成對(duì)應(yīng)的ApplicationArguments,
  • 此處步驟會(huì)先準(zhǔn)備對(duì)應(yīng)環(huán)境,主要是我們?cè)谂渲玫呐渲眯畔⒌鸟{照,在完成環(huán)境準(zhǔn)備之后在listeners.environmentPrepared(environment); 方法中會(huì)回調(diào)SpringApplicationRunListener中的environmentPrepared 事件,也是同樣的異步的方式觸發(fā)
  • 這個(gè)步驟pringBanner,啟動(dòng)時(shí)候banner的打印,可以自定義自步驟中的圖形
  • createApplicationContext方法會(huì)更具我們之前環(huán)境判斷信來(lái)是web環(huán)境還是其他決定創(chuàng)建web還是普通的IOC容器
  • 此步驟中有多個(gè)功能
  • 將environment上下文環(huán)境信息保存早ioc容器中
  • 執(zhí)行applyInitializers 方法,改方法會(huì)遍歷之前保存的ApplicationContextInitializer的initialize()事件
  • 在contextPerpared中遍歷SpringApplicationRunListener中的ContextPrepared()事件
  • 最后在contextLoaded方法中回調(diào)SpringApplicationRunListener中的ContextLoaded()事件
  • refreshContext顧名思義,刷新容器,進(jìn)行組件的掃描創(chuàng)建,加載等
  • afterRefresh從IOC容器中獲取所有ApplicationRunner和CommandLineRunner遍歷所有runner并且調(diào)用callRunner方法回調(diào)用,先調(diào)用ApplicationRunner,在調(diào)用CommandLineRunner
  • finished方法中遍歷SpringApplicationRunListener中的finished()事件
  • 最后返回context ioc容器
  • 總結(jié)
    • SpringApplication.run一共做了兩件事,一件是創(chuàng)建SpringApplication對(duì)象,在該對(duì)象初始化時(shí),找到配置的事件監(jiān)聽(tīng)器,并保存起來(lái).第二件事就是運(yùn)行run方法,此時(shí)會(huì)將剛才保存的事件監(jiān)聽(tīng)器根據(jù)當(dāng)前時(shí)機(jī)觸發(fā)不同的事件,比如容器初始化,容器創(chuàng)建完成等.同時(shí)也會(huì)刷新IoC容器,進(jìn)行組件的掃描、創(chuàng)建、加載等工作.

    總結(jié)

    以上是生活随笔為你收集整理的SpringApplication.run做了哪些事情的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。