SpringBoot啟動(dòng)流程之環(huán)境準(zhǔn)備

整體流程

SpringBoot啟動(dòng)過程:


springboot啟動(dòng)過程

上一節(jié)我們討論SpringApplication實(shí)例化的過程塔次,也就是上圖1-9步驟塔嬉,本節(jié)我們討論10關(guān)鍵步驟拍顷,現(xiàn)在主要講是run方法里面的過程

   /**
     * 啟動(dòng)方法
     * @param args
     * @return
     */
    public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        //....省略

        try {
            //包裝參數(shù)變量
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            //準(zhǔn)備環(huán)境
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            //......此處省略代碼
  
    }

準(zhǔn)備環(huán)境

準(zhǔn)備環(huán)境是一個(gè)重要的方法蕊退,主要幫我們配置Java一些環(huán)境茫蛹,把Java環(huán)境屬性加載到內(nèi)存魁蒜,管理起來囊扳,方便我們以后使用吩翻,源碼如下:

 /**
     *  環(huán)境準(zhǔn)備
     * @param listeners 監(jiān)聽管理器
     * @param applicationArguments 啟動(dòng)參數(shù)
     * @return 返回標(biāo)準(zhǔn)的servlet環(huán)境
     */
    private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {
        // 創(chuàng)建一個(gè)新的 ConfigurableEnvironment 實(shí)例或檢索現(xiàn)有實(shí)例。
        ConfigurableEnvironment environment = this.getOrCreateEnvironment();

        // 根據(jù)命令行參數(shù)配置環(huán)境锥咸。
        this.configureEnvironment((ConfigurableEnvironment) environment, applicationArguments.getSourceArgs());

        // 將配置屬性源附加到環(huán)境中狭瞎。
        ConfigurationPropertySources.attach((Environment) environment);

        // 通知監(jiān)聽器環(huán)境已準(zhǔn)備好。
        listeners.environmentPrepared((ConfigurableEnvironment) environment);

        // 將環(huán)境綁定到 Spring 應(yīng)用程序她君。
        this.bindToSpringApplication((ConfigurableEnvironment) environment);

        // 檢查是否設(shè)置了自定義環(huán)境脚作。
        if (!this.isCustomEnvironment) {
            // 如果需要,使用 EnvironmentConverter 轉(zhuǎn)換環(huán)境(例如缔刹,用于類加載)球涛。
            environment = (new EnvironmentConverter(this.getClassLoader()))
                    .convertEnvironmentIfNecessary((ConfigurableEnvironment) environment, this.deduceEnvironmentClass());
        }

        // 再次附加配置屬性源(如果需要)。
        ConfigurationPropertySources.attach((Environment) environment);

        // 返回準(zhǔn)備好的環(huán)境校镐。
        return (ConfigurableEnvironment) environment;
    }

實(shí)例化StandardServletEnvironment對(duì)象

StandardServletEnvironment的父類是StandardEnvironment亿扁,而StandardEnvironment的抽象父類是AbstractEnvironment。類圖如下

環(huán)境類圖

在實(shí)例化StandardServletEnvironment的時(shí)候鸟廓,主要是抽象父類添加兩類屬性資源servletContextInitParamsservletConfigInitParams从祝,在StandardEnvironment中又添加了兩類屬性資源systemPropertiessystemEnvironment

  • servletContextInitParams:servlet上下文初始化屬性資源引谜,屬性值目前是一個(gè)obj對(duì)象牍陌。
  • servletConfigInitParams:servlet配置的屬性資源,屬性值目前也是一個(gè)obj對(duì)象员咽。
  • systemProperties:Java環(huán)境屬性資源毒涧。
  • systemEnvironment:操作系統(tǒng)環(huán)境屬性資源。

configureEnvironment配置環(huán)境

改方法主要做三件事贝室,1契讲,是配置環(huán)境的裝換服務(wù)對(duì)象。2滑频,是配置參數(shù)屬性捡偏,就是命令行傳的參數(shù)。3峡迷,配置活躍的環(huán)境银伟,現(xiàn)階段是空。代碼如下

    /**
     * 配置環(huán)境
     * @param environment 環(huán)境對(duì)象
     * @param args 命令參數(shù)
     */
    protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
        //這里是true
        if (this.addConversionService) {
            ConversionService conversionService = ApplicationConversionService.getSharedInstance();
            //設(shè)置ConfigurableConversionService對(duì)象
            environment.setConversionService((ConfigurableConversionService)conversionService);
        }
        //配置命令行參數(shù)
        this.configurePropertySources(environment, args);
        //配置活躍的環(huán)境绘搞,暫時(shí)是空
        this.configureProfiles(environment, args);
    }

附加配置屬性

ConfigurationPropertySources.attach((Environment) environment);附加配置屬性資源彤避,之前我們加了四個(gè),現(xiàn)在多個(gè)叫configurationProperties的屬性資源名看杭。這里附加的屬性資源并無任務(wù)的值。

廣播環(huán)境準(zhǔn)備完成事件

listeners.environmentPrepared((ConfigurableEnvironment) environment);廣播事件挟伙,下面我們看看支持那些監(jiān)聽器楼雹,并且做了什么事情模孩。符合條件只要7個(gè)監(jiān)聽器,最重要的是ConfigFileApplicationListener,這個(gè)類就是加載我們配置文件贮缅。

ConfigFileApplicationListener

監(jiān)聽器處理方法榨咐,就是在META-INF下的spring.factories下面的接口EnvironmentPostProcessor的實(shí)現(xiàn)類,同時(shí)也把ConfigFileApplicationListener加入到 環(huán)境處理列表中谴供,加載處理實(shí)例一共是五個(gè)块茁,其中兩個(gè)是沒什么用的,源碼如下

    //處理事件
    private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
        //META-INF/spring.factories下的EnvironmentPostProcessor的所有實(shí)現(xiàn)類
        List<EnvironmentPostProcessor> postProcessors = this.loadPostProcessors();
        //添加到列表
        postProcessors.add(this);
        AnnotationAwareOrderComparator.sort(postProcessors);
        Iterator<EnvironmentPostProcessor> it = postProcessors.iterator();

        while(it.hasNext()) {
            EnvironmentPostProcessor postProcessor = it.next();
            //處理配置環(huán)境
            postProcessor.postProcessEnvironment(event.getEnvironment(), event.getSpringApplication());
        }
    }

ConfigFileApplicationListener中桂肌,有個(gè)Loader內(nèi)部類数焊,這個(gè)內(nèi)部類初始化會(huì)去META-INF/spring.factories去找對(duì)應(yīng)的屬性加載器,一共找到兩個(gè)PropertiesPropertySourceLoaderYamlPropertySourceLoader崎场,分別處理yml文件和properties后綴的文件佩耳。

    Loader(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
        this.logger = ConfigFileApplicationListener.this.logger;
        this.loadDocumentsCache = new HashMap<>();
        this.environment = environment;
        //解析參數(shù)
        this.placeholdersResolver = new PropertySourcesPlaceholdersResolver(this.environment);
        this.resourceLoader = (ResourceLoader)(resourceLoader != null ? resourceLoader : new DefaultResourceLoader((ClassLoader)null));
        //屬性文件加載列表
        this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class, this.getClass().getClassLoader());
    }

程序執(zhí)行到這里,所有的配置屬性都加載到環(huán)境中谭跨,包括外部配置和內(nèi)部配置干厚。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市螃宙,隨后出現(xiàn)的幾起案子蛮瞄,更是在濱河造成了極大的恐慌,老刑警劉巖谆扎,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挂捅,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡燕酷,警方通過查閱死者的電腦和手機(jī)籍凝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來苗缩,“玉大人饵蒂,你說我怎么就攤上這事〗囱龋” “怎么了退盯?”我有些...
    開封第一講書人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)泻肯。 經(jīng)常有香客問我渊迁,道長(zhǎng),這世上最難降的妖魔是什么灶挟? 我笑而不...
    開封第一講書人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任琉朽,我火速辦了婚禮,結(jié)果婚禮上稚铣,老公的妹妹穿的比我還像新娘箱叁。我一直安慰自己墅垮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開白布耕漱。 她就那樣靜靜地躺著算色,像睡著了一般。 火紅的嫁衣襯著肌膚如雪螟够。 梳的紋絲不亂的頭發(fā)上灾梦,一...
    開封第一講書人閱讀 50,084評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音妓笙,去河邊找鬼若河。 笑死,一個(gè)胖子當(dāng)著我的面吹牛给郊,可吹牛的內(nèi)容都是我干的牡肉。 我是一名探鬼主播,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼淆九,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼统锤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起炭庙,我...
    開封第一講書人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤饲窿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后焕蹄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逾雄,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年腻脏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鸦泳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡永品,死狀恐怖做鹰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鼎姐,我是刑警寧澤钾麸,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站炕桨,受9級(jí)特大地震影響饭尝,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜献宫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一钥平、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧姊途,春花似錦涉瘾、人聲如沸奈惑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至寂殉,卻和暖如春囚巴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背友扰。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工彤叉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人村怪。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓秽浇,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親甚负。 傳聞我的和親對(duì)象是個(gè)殘疾皇子柬焕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

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