科技改變生活 · 科技引領(lǐng)未來
在springboot中environment主要用來保存我們的配置,它主要包括兩個(gè)方面,profiles 和 properties。profiles指的就是我們的多環(huán)境(開發(fā),測(cè)試,生成等),切換不同的profiles就會(huì)切換不同的bean和配置文件。而properties 就是我們經(jīng)常使用的key-value鍵值對(duì)集合。
application.run方法
上圖就是springboot應(yīng)用啟動(dòng)過程,包括創(chuàng)建environment,準(zhǔn)備創(chuàng)建context,發(fā)布監(jiān)聽事件,啟動(dòng)runers (ApplicationRunner、commandLineRunner等啟動(dòng)器)。
getOrCreateEnvironment 整個(gè)過程包括創(chuàng)建和配置environment,以及發(fā)布environment準(zhǔn)備通知事件,我們可以通過監(jiān)聽此事件在代碼中新增或者更改我們的environment的環(huán)境變量。
1、創(chuàng)建ConfigurableEnvironment。如果是WebApplicationType.SERVLET 就會(huì)返回StandardServletEnvironment,因?yàn)槲覀兌际莝pringboot web應(yīng)用程序所以這里返回StandardServletEnvironment。
private ConfigurableEnvironment getOrCreateEnvironment() { if (this.environment != null) { return this.environment; } if (this.webApplicationType == WebApplicationType.SERVLET) { return new StandardServletEnvironment(); } return new StandardEnvironment();}
初始創(chuàng)建的environment
初始創(chuàng)建的environment
2、configureEnviroment配置environment。這里配置包括上面一節(jié)提到過的兩個(gè)功能—property和profiles。這里面只做了初始化的功能,這里并未真正的加載例如application.properties/yml的propeties以及profile。
protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) { configurePropertySources(environment, args); configureProfiles(environment, args);}
3、發(fā)布environmentPrepared的ApplicationEnvironmentPreparedEvent事件。
public void environmentPrepared(ConfigurableEnvironment environment) { for (SpringApplicationRunListener listener : this.listeners) { listener.environmentPrepared(environment); }}@Overridepublic void environmentPrepared(ConfigurableEnvironment environment) {this.initialMulticaster.multicastEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment));}
ApplicationEnvironmentPreparedEvent的監(jiān)聽器
首先會(huì)獲取到所有的監(jiān)聽器,然后觸發(fā)這些監(jiān)聽器,這里我們以ConfigFileApplicaationListener
為例,ConfigFileApplicationListener會(huì)讀取配置文件,并加載到environment中的PropertySources列表中。首先會(huì)加載當(dāng)前激活的profile列表,然后從classpath:/,classpath:/config/,file:./,file:./config/ 找到 application-{profile}的配置文件(可通過spring.config.location 配置文件搜索路徑)。
處理environmentPreparedEvent的判斷邏輯
** 代碼獲取所有監(jiān)聽器,遍歷循環(huán),執(zhí)行postProcessEnvironment后置處理 ** private void onApplicationEnvironmentPreparedEvent( ApplicationEnvironmentPreparedEvent event) { List postProcessors = loadPostProcessors(); postProcessors.add(this); ConfigFileApplicationListener本身也是postProcessor AnnotationAwareOrderComparator.sort(postProcessors); for (EnvironmentPostProcessor postProcessor : postProcessors) { postProcessor.postProcessEnvironment(event.getEnvironment(), event.getSpringApplication()); }}
4、幾個(gè)常見監(jiān)聽器處理邏輯
SystemEnvironmentPropertySourceEnvironmentPostProcessor:替換系統(tǒng)的環(huán)境變量USERDOMAIN_ROAMINGPROFILE -> LLS,JAVA_HOME -> C:Program FilesJavajdk1.8.0_151等。
ConfigFileApplicationListener:添加RandomValuePropertySource,加載profile 例如‘dev’ ,根據(jù)這個(gè)dev profile環(huán)境,加載config文件的property source到environment。下圖所示即已加載了多個(gè)PropertySource(random、applicaton-docker-dev.yml、application-properties等)
已加載至環(huán)境中的PropertySources
擴(kuò)展:自定義EnvironmentPostProcessor
springboot提供EnvironmentPostProcessor接口用于environment后處理。在實(shí)現(xiàn)postProcessEnvironment的方法中可以加載任何想需要的屬性到environment中。
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { Properties pros = new Properties(); pros.setProperty(&34;woshiyizhiwugui&34;, &34;我是一個(gè)小烏龜&34;); PropertiesPropertySource propertiesPropertySource = new PropertiesPropertySource(fileName, pros); environment.getPropertySources().addLast(propertiesPropertySource);environment.setRequiredProperties(&34;helloworld&34;); //設(shè)置必須要有的屬性,如果未配置,springboot啟動(dòng)異常}
dubbo擴(kuò)展的DubboDefaultPropertiesEnvironmentPostProcessor
王楠東
版權(quán)所有 未經(jīng)許可不得轉(zhuǎn)載
增值電信業(yè)務(wù)經(jīng)營(yíng)許可證備案號(hào):遼ICP備14006349號(hào)
網(wǎng)站介紹 商務(wù)合作 免責(zé)聲明 - html - txt - xml