02--SpringBoot啟動源碼簡單分析

打開SampleSimpleApplication.java,我們可以看到

public static void main(String[] args) {
    //SpringBoot啟動函數(shù)
    SpringApplication.run(SampleSimpleApplication.class, args);
}

跟蹤進(jìn)去,可看到

public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
    return run(new Class<?>[]{primarySource}, args);
}

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
    return new SpringApplication(primarySources).run(args);
}

其中return new SpringApplication(primarySources).run(args);為核心方法,創(chuàng)建SpringApplication實例并執(zhí)行run()方法,接下來我們對這句話進(jìn)行分析.

1. 創(chuàng)建SpringApplication實例

public SpringApplication(Class<?>... primarySources) {
    this(null, primarySources);
}

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    //resourceLoader賦值給this.resourceLoader
    this.resourceLoader = resourceLoader;
    //斷言
    Assert.notNull(primarySources, "PrimarySources must not be null");
    //將primarySources存入LinkedHashSet對象并賦值給this.primarySources
    this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
    //推斷當(dāng)前應(yīng)用類型
    this.webApplicationType = deduceWebApplicationType();
    //初始化Initializer
    setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
    //初始化Listener
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    //推斷主類
    this.mainApplicationClass = deduceMainApplicationClass();
    }

2. 執(zhí)行run()完成SpringBoot啟動

public ConfigurableApplicationContext run(String... args) {
    //創(chuàng)建StopWatch對象,用來記錄程序啟動耗時
    StopWatch stopWatch = new StopWatch();
    //啟動
    stopWatch.start();
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
    configureHeadlessProperty();
    //根據(jù)args獲取所有SpringApplicationRunListeners監(jiān)聽器
    SpringApplicationRunListeners listeners = getRunListeners(args);
    //啟動監(jiān)聽器,首次啟動run方法時立即調(diào)用
    listeners.starting();
    try {
        //創(chuàng)建ApplicationArguments對象,并將args封裝至對象實例
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        //準(zhǔn)備環(huán)境
        ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
        //配置需要忽略的bean
        configureIgnoreBeanInfo(environment);
        //打印banner
        Banner printedBanner = printBanner(environment);
        //創(chuàng)建應(yīng)用上下文對象
        context = createApplicationContext();
        //獲取異常報告對象
        exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
        //準(zhǔn)備上下文環(huán)境
        prepareContext(context, environment, listeners, applicationArguments, printedBanner);
        //刷新上下文
        refreshContext(context);
        //刷新上下文后續(xù)處理
        afterRefresh(context, applicationArguments);
        //關(guān)閉stopWatch
        stopWatch.stop();
        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
        }
        //執(zhí)行監(jiān)聽器started方法
        listeners.started(context);
        callRunners(context, applicationArguments);
        } catch (Throwable ex) {
            handleRunFailure(context, ex, exceptionReporters, listeners);
            throw new IllegalStateException(ex);
        }
        try {
            //在run方法完成之前立即調(diào)用井厌,刷新應(yīng)用程序上下文并且所有的CommandLineRunners和ApplicationRunners已經(jīng)被調(diào)用
            listeners.running(context);
        } catch (Throwable ex) {
            handleRunFailure(context, ex, exceptionReporters, null);
            throw new IllegalStateException(ex);
        }
        return context;
    }

至此,我們已經(jīng)可以大概了解到SpringBoot的啟動流程,因為啟動過程中的一些方法比較復(fù)雜,所以我們接下來會分篇幅介紹其中一些核心的方法...

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末禽拔,一起剝皮案震驚了整個濱河市艳馒,隨后出現(xiàn)的幾起案子漾橙,更是在濱河造成了極大的恐慌惶室,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件闻蛀,死亡現(xiàn)場離奇詭異主巍,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)碱蒙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門荠瘪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赛惩,你說我怎么就攤上這事哀墓。” “怎么了喷兼?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵篮绰,是天一觀的道長。 經(jīng)常有香客問我季惯,道長吠各,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任勉抓,我火速辦了婚禮贾漏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘藕筋。我一直安慰自己纵散,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著困食,像睡著了一般。 火紅的嫁衣襯著肌膚如雪翎承。 梳的紋絲不亂的頭發(fā)上硕盹,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機(jī)與錄音叨咖,去河邊找鬼瘩例。 笑死,一個胖子當(dāng)著我的面吹牛甸各,可吹牛的內(nèi)容都是我干的垛贤。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼趣倾,長吁一口氣:“原來是場噩夢啊……” “哼聘惦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起儒恋,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤善绎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后诫尽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體禀酱,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年牧嫉,在試婚紗的時候發(fā)現(xiàn)自己被綠了剂跟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡酣藻,死狀恐怖曹洽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情臊恋,我是刑警寧澤衣洁,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站抖仅,受9級特大地震影響坊夫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜撤卢,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一环凿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧放吩,春花似錦智听、人聲如沸赌躺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酥泛。三九已至,卻和暖如春莉测,著一層夾襖步出監(jiān)牢的瞬間颜骤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工捣卤, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留忍抽,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓董朝,卻偏偏與公主長得像鸠项,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子子姜,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容