SpringBoot run方法

    public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
        //設(shè)置系統(tǒng)屬性『java.awt.headless』,為true則啟用headless模式支持
        this.configureHeadlessProperty();
/*通過SpringFactoriesLoader檢索META-INF/spring.factories,
 找到聲明的所有SpringApplicationRunListener的實(shí)現(xiàn)類并將其實(shí)例化,
 之后逐個(gè)調(diào)用其started()方法,廣播SpringBoot要開始執(zhí)行了
*/
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        //發(fā)布應(yīng)用開始啟動(dòng)事件
        listeners.starting();

        Collection exceptionReporters;
        try {
            //初始化參數(shù)
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
/*
創(chuàng)建并配置當(dāng)前SpringBoot應(yīng)用將要使用的Environment
(包括配置要使用的PropertySource以及Profile)
并遍歷調(diào)用所有的SpringApplicationRunListener的environmentPrepared()方法,
 廣播Environment準(zhǔn)備完畢。
*/
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            //打印banner
            Banner printedBanner = this.printBanner(environment);
            //創(chuàng)建應(yīng)用上下文
            context = this.createApplicationContext();
//通過*SpringFactoriesLoader*檢索*META-INF/spring.factories*,獲取并實(shí)例化異常分析器
            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
            /*
為ApplicationContext加載environment,
之后逐個(gè)執(zhí)行ApplicationContextInitializer的initialize()方法來進(jìn)一步封裝ApplicationContext,
并調(diào)用所有的SpringApplicationRunListener的contextPrepared()方法【EventPublishingRunListener只提供了一個(gè)空的contextPrepared()方法】,
之后初始化IoC容器,并調(diào)用SpringApplicationRunListener的contextLoaded()方法,廣播ApplicationContext的IoC加載完成,
這里就包括通過@EnableAutoConfiguration導(dǎo)入的各種自動(dòng)配置類。
            */
            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            //刷新上下文
            this.refreshContext(context);
            //再一次刷新上下文,其實(shí)是空方法,可能是為了后續(xù)擴(kuò)展。
            this.afterRefresh(context, applicationArguments);
            stopWatch.stop();
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }
            //發(fā)布應(yīng)用已經(jīng)啟動(dòng)的事件
            listeners.started(context);
          /*
          遍歷所有注冊(cè)的ApplicationRunner和CommandLineRunner,并執(zhí)行其run()方法。
          我們可以實(shí)現(xiàn)自己的ApplicationRunner或CommandLineRunner,來對(duì)SpringBoot的啟動(dòng)過程進(jìn)行擴(kuò)展。
          */
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            this.handleRunFailure(context, var10, exceptionReporters, listeners);
            throw new IllegalStateException(var10);
        }

        try {
            //應(yīng)用已經(jīng)啟動(dòng)完成的監(jiān)聽事件
            listeners.running(context);
            return context;
        } catch (Throwable var9) {
            this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }
    }

總結(jié)下步驟為:

  1. 配置屬性
  2. 獲取監(jiān)聽器,發(fā)布應(yīng)用開始啟動(dòng)事件
  3. 初始化輸入?yún)?shù)
  4. 配置環(huán)境,輸出banner
  5. 創(chuàng)建上下文
  6. 預(yù)處理上下文
  7. 刷新上下文
  8. 再刷新上下文
  9. 發(fā)布應(yīng)用已經(jīng)啟動(dòng)事件
  10. 發(fā)布應(yīng)用啟動(dòng)完成事件

而啟動(dòng)Tomcat就是在第7步中“刷新上下文”;Tomcat的啟動(dòng)主要是初始化2個(gè)核心組件,連接器(Connector)和容器(Container),一個(gè)Tomcat實(shí)例就是一個(gè)Server,一個(gè)Server包含多個(gè)Service,也就是多個(gè)應(yīng)用程序,每個(gè)Service包含多個(gè)連接器(Connetor)和一個(gè)容器(Container),而容器下又有多個(gè)子容器,按照父子關(guān)系分別為:Engine,Host,Context,Wrapper,其中除了Engine外,其余的容器都是可以有多個(gè)。

?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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