- apollo主要功能就是獲取配置,動(dòng)態(tài)更新配置,spring內(nèi)部配置存在Environment里,所以Environment是apollo接入spring的關(guān)鍵點(diǎn)之一
Environment主要用途:
- 配置存儲(chǔ):從各種數(shù)據(jù)源(PropertySource)獲取配置,每個(gè)配置以KV的形式存在Environment,數(shù)據(jù)源包括配置文件、環(huán)境變量、系統(tǒng)變量等等
- Profiles切換:Environment還支持多Profiles,根據(jù)Profiles加載配置、Bean
- 處理占位符:替換配置里的占位符
Environment的使用:
- Environment對(duì)象默認(rèn)已經(jīng)初始化在IOC容器里,但是直接使用Environment對(duì)象的場(chǎng)景并不多,@Value和@ConfigurationProperties間接用來獲取數(shù)據(jù)的場(chǎng)景的比較多
- Environment除了默認(rèn)數(shù)據(jù)源還可以添加自定義數(shù)據(jù)源和配置!這個(gè)就是apollo操作的重點(diǎn)之一
Environment相關(guān)補(bǔ)充:
- Environment加載數(shù)據(jù)源在prepareEnvironment階段,初始化spring context之前
- 處理@Value在BeanFactoryPostProcessor階段,找到所有@Value標(biāo)記的變量,從Environment找出配置替換掉,手動(dòng)操作Environment可以實(shí)現(xiàn)apollo放入遠(yuǎn)程配置
- @ConfigurationProperties同樣,只是@ConfigurationProperties是通過bean的形式獲取Environment的配置
-
下面是一個(gè)environment樣例,其中三個(gè)標(biāo)記的數(shù)據(jù)源分別是系統(tǒng)參數(shù)、application.properties、自定義的配置文件,排序越靠前的獲取優(yōu)先級(jí)越高
Environment - 替換配置源demo:
/**
* 替換environment里的數(shù)據(jù),environment可以通過EnvironmentAware等等方式直接獲取
* @param propertySource 數(shù)據(jù)源的名字
* @param key 替換的key
* @param newValue 替換的新值
*/
public void replaceProperties(String propertySource, String key, String newValue){
// environment的配置源集合里有系統(tǒng)變量、配置文件等等
MutablePropertySources propertySources = environment.getPropertySources();
if(propertySources.contains(propertySource)){
// 獲取目標(biāo)數(shù)據(jù)源
PropertySource<?> bootstrapPropertySource = propertySources.get(propertySource);
// 創(chuàng)建新的propertySource覆蓋掉老的propertySource
Object source = bootstrapPropertySource.getSource();
if (source instanceof Map) {
// 刪除舊的
propertySources.remove(propertySource);
Map<String, Object> externalProperties = new HashMap<>((Map<String, Object>) source);
externalProperties.put(key, newValue);
MapPropertySource newPropertySource = new MapPropertySource(propertySource, externalProperties);
// 添加新的數(shù)據(jù)源到優(yōu)先級(jí)最高的位置
propertySources.addFirst(newPropertySource);
}
}
}
public void print(String key) throws BeansException {
// 使用environment獲取配置
System.out.println("Environment-----" + environment.getProperty(key));
}
