springboot啟動(dòng)流程3-完善上下文bean加載器(prepareContext)

  • 前言

    上文已經(jīng)創(chuàng)建了上下文對(duì)象匆篓,并初始化了bean的工廠類,加載了對(duì)部分注解的支持類惧互。
    本文將在此基礎(chǔ)上繼續(xù)介紹上下文對(duì)象的進(jìn)一步信息完善鳍刷。

    文章基于springboot2.3.x系列的源碼(大部分以jar包中的源碼為例講解)鱼的,github的源碼與實(shí)際發(fā)版的可能略微不同理盆,不過(guò)整體流程差別不大。
    本人第一次寫文章鸳吸,如有錯(cuò)誤或誤導(dǎo)歡迎留言指正熏挎。文章整體可能比較啰嗦,盡可能的將流程中的每一個(gè)重要的方法都講到晌砾。

1. prepareContext

源碼:

```
 private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
    //注入環(huán)境屬性
    context.setEnvironment(environment);
    //上下文后置處理
    this.postProcessApplicationContext(context);
    //完善初始化類的屬性
    this.applyInitializers(context);
    //發(fā)送監(jiān)聽事件
    listeners.contextPrepared(context);
    //日志
    if (this.logStartupInfo) {
        this.logStartupInfo(context.getParent() == null);
        this.logStartupProfileInfo(context);
    }
    //注冊(cè)傳入的配置參數(shù)為bean坎拐,這里將傳入的參數(shù)封裝成applicationArguments,內(nèi)部類似命令行
    ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
    beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
    //banner打印
    if (printedBanner != null) {
        beanFactory.registerSingleton("springBootBanner", printedBanner);
    }
    //這里默認(rèn)情況下bean定義不允許重復(fù)
    if (beanFactory instanceof DefaultListableBeanFactory) {
        ((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
    }
    //默認(rèn)不開啟延遲加載
    if (this.lazyInitialization) {
        context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
    }
    //獲取全部的資源
    //這里獲取了啟動(dòng)類的資源和 當(dāng)前SpringApplication中的source資源养匈。
    //到目前來(lái)說(shuō)實(shí)際上只有啟動(dòng)類資源
    Set<Object> sources = this.getAllSources();
    Assert.notEmpty(sources, "Sources must not be empty");
    this.load(context, sources.toArray(new Object[0]));
    listeners.contextLoaded(context);
}
```

老樣子進(jìn)行逐個(gè)分析哼勇。但看這個(gè)方法并不復(fù)雜,整體上對(duì)上下文和工廠類進(jìn)行配置的完善呕乎。

1.1 postProcessApplicationContext 方法

源碼:

   protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
        //  是否自定義bean名稱生成類
        if (this.beanNameGenerator != null) {
            context.getBeanFactory().registerSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator", this.beanNameGenerator);
        }
        //是否指定類加載器
        if (this.resourceLoader != null) {
            if (context instanceof GenericApplicationContext) {
                ((GenericApplicationContext)context).setResourceLoader(this.resourceLoader);
            }

            if (context instanceof DefaultResourceLoader) {
                ((DefaultResourceLoader)context).setClassLoader(this.resourceLoader.getClassLoader());
            }
        }
        
        //是否添加數(shù)據(jù)轉(zhuǎn)換器 
        //在初始化環(huán)境對(duì)象的時(shí)候也有用到积担,這里可以直接通過(guò) context.getEnvironment().getConversionService()獲取到
        if (this.addConversionService) {
            context.getBeanFactory().setConversionService(ApplicationConversionService.getSharedInstance());
        }
    }

1.2 applyInitializers

完善與ApplicationContextInitializer接口相關(guān)的對(duì)象屬性,同時(shí)也可以對(duì)上下文屬性進(jìn)行配置猬仁。這些對(duì)象在this.initializers中,早在SpringApplication初始化的時(shí)候就已經(jīng)加載帝璧。通過(guò)已經(jīng)初始化好的上下文對(duì)相關(guān)類進(jìn)行完善。調(diào)用接口的initialize方法湿刽。

1.3 load

源碼:

    protected void load(ApplicationContext context, Object[] sources) {
        if (logger.isDebugEnabled()) {
            logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
        }
        //構(gòu)建一個(gè)bean定義的加載器
        BeanDefinitionLoader loader = createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources);
        if (this.beanNameGenerator != null) {
            loader.setBeanNameGenerator(this.beanNameGenerator);
        }
        if (this.resourceLoader != null) {
            loader.setResourceLoader(this.resourceLoader);
        }
        if (this.environment != null) {
            loader.setEnvironment(this.environment);
        }
        //將資源加載成bean
        loader.load();
    }
    
    void load() {
        for (Object source : this.sources) {
            load(source);
        }
    }
    //按資源類型分別進(jìn)行加載的烁,
    private void load(Object source) {
        Assert.notNull(source, "Source must not be null");
        if (source instanceof Class<?>) {
            load((Class<?>) source);
            return;
        }
        if (source instanceof Resource) {
            load((Resource) source);
            return;
        }
        if (source instanceof Package) {
            load((Package) source);
            return;
        }
        if (source instanceof CharSequence) {
            load((CharSequence) source);
            return;
        }
        throw new IllegalArgumentException("Invalid source type " + source.getClass());
    }

主要加載了SpringApplication內(nèi)初始化的資源,包括我們的啟動(dòng)類xxApplication將會(huì)被注冊(cè)成bean诈闺。

小結(jié)

繼上下文創(chuàng)建完成后渴庆,又對(duì)其進(jìn)行了一些屬性的初始化,并加載了一些配置資源雅镊。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末襟雷,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子仁烹,更是在濱河造成了極大的恐慌耸弄,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,348評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晃危,死亡現(xiàn)場(chǎng)離奇詭異叙赚,居然都是意外死亡老客,警方通過(guò)查閱死者的電腦和手機(jī)僚饭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門震叮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人鳍鸵,你說(shuō)我怎么就攤上這事苇瓣。” “怎么了偿乖?”我有些...
    開封第一講書人閱讀 156,936評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵击罪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我贪薪,道長(zhǎng)媳禁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,427評(píng)論 1 283
  • 正文 為了忘掉前任画切,我火速辦了婚禮竣稽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘霍弹。我一直安慰自己毫别,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評(píng)論 6 385
  • 文/花漫 我一把揭開白布典格。 她就那樣靜靜地躺著岛宦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪耍缴。 梳的紋絲不亂的頭發(fā)上砾肺,一...
    開封第一講書人閱讀 49,785評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音防嗡,去河邊找鬼变汪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛本鸣,可吹牛的內(nèi)容都是我干的疫衩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,931評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼荣德,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼闷煤!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起涮瞻,我...
    開封第一講書人閱讀 37,696評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鲤拿,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后署咽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體近顷,經(jīng)...
    沈念sama閱讀 44,141評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡生音,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了窒升。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缀遍。...
    茶點(diǎn)故事閱讀 38,625評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖饱须,靈堂內(nèi)的尸體忽然破棺而出域醇,到底是詐尸還是另有隱情,我是刑警寧澤蓉媳,帶...
    沈念sama閱讀 34,291評(píng)論 4 329
  • 正文 年R本政府宣布譬挚,位于F島的核電站,受9級(jí)特大地震影響酪呻,放射性物質(zhì)發(fā)生泄漏减宣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評(píng)論 3 312
  • 文/蒙蒙 一玩荠、第九天 我趴在偏房一處隱蔽的房頂上張望漆腌。 院中可真熱鬧,春花似錦姨蟋、人聲如沸屉凯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)悠砚。三九已至,卻和暖如春堂飞,著一層夾襖步出監(jiān)牢的瞬間灌旧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工绰筛, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留枢泰,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓铝噩,卻偏偏與公主長(zhǎng)得像衡蚂,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子骏庸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評(píng)論 2 348

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