上來先來個例子
import org.junit.jupiter.api.Test;
import org.springframework.core.env.*;
import org.springframework.util.StringUtils;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* @author lwh
* @date 2022/3/17
*/
public class PropertySourceTest {
@Test
public void test01(){
class MyMapPropertySource extends EnumerablePropertySource<Map<String,Object>>{
public MyMapPropertySource(String name, Map<String,Object> source) {
super(name, source);
}
@Override
public boolean containsProperty(String name) {
return this.source.containsKey(name);
}
@Override
public String[] getPropertyNames() {
return StringUtils.toStringArray(this.source.keySet());
}
@Override
public Object getProperty(String name) {
return this.source.get(name);
}
}
final HashMap<String, Object> lwhHashMap = new HashMap<>();
lwhHashMap.put("lwh",123);
lwhHashMap.put("ai","${USERNAME}");
final MyMapPropertySource lwh = new MyMapPropertySource("lwh", lwhHashMap);
final HashMap<String, Object> lsfHashMap = new HashMap<>();
lsfHashMap.put("lsf",456);
//只是一個迭代器而然
final MyMapPropertySource lsf = new MyMapPropertySource("lsf", lsfHashMap);
//可以自定義PropertySources,但是也沒必要
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addLast(lwh);
propertySources.addLast(lsf);
//需要解析器,自定義的解析器蛾坯,你可以選擇實現(xiàn)PropertySourcesPropertyResolver 或者AbstractPropertyResolver
//PropertySourcesPropertyResolver propertySourcesPropertyResolver = new PropertySourcesPropertyResolver(propertySources);
class MyPropertySourcesPropertyResolver extends PropertySourcesPropertyResolver{
public MyPropertySourcesPropertyResolver(PropertySources propertySources) {
super(propertySources);
}
//沒必要實現(xiàn)
@Override
protected String getPropertyAsRawString(String key) {
return super.getPropertyAsRawString(key);
}
//沒必要實現(xiàn)
@Override
protected <T> T getProperty(String key, Class<T> targetValueType, boolean resolveNestedPlaceholders) {
return super.getProperty(key, targetValueType, resolveNestedPlaceholders);
}
}
//自定義加載系統(tǒng)的環(huán)境變量進來仲墨,也可以加載其他的環(huán)境變量
class MyStandardEnvironment extends AbstractEnvironment{
public MyStandardEnvironment(MutablePropertySources propertySources) {
super(propertySources);
}
@Override
protected ConfigurablePropertyResolver createPropertyResolver(MutablePropertySources propertySources) {
return new MyPropertySourcesPropertyResolver(propertySources);
}
//可以自定義的加入自己的MyMapPropertySource
@Override
protected void customizePropertySources(MutablePropertySources propertySources) {
super.customizePropertySources(propertySources);
propertySources.addLast(
new MapPropertySource("SystemProperties", getSystemProperties()));
propertySources.addLast(
new SystemEnvironmentPropertySource("SystemEnvironment", getSystemEnvironment()));
}
}
MyStandardEnvironment myStandardEnvironment = new MyStandardEnvironment(propertySources);
final String ai = myStandardEnvironment.getProperty("ai");
System.out.println(ai);
}
}
在貼一張類圖
說明一下勾缭,我希望你自己去看,畢竟目养,我能力有限俩由,寫上去的也不一定對
1.PropertySource
這個是一個抽象類,你可以繼承這個類癌蚁,定制自己的PropertySource 幻梯,已有的子類有
EnumerablePropertySource,MapPropertySource等努释,其實這個類就是一個name和source的屬性值得關(guān)注碘梢,
name可以說名是哪一個配置文件,source就是配置文件的內(nèi)容伐蒂,比如MapPropertySource的name是字符串
source就是Map<String,Object>煞躬,還有就是可以PropertySource.getProperty(“配置文件內(nèi)容中的key”)得到配置文件內(nèi)容中的value
PropertySources 其實就是一個PropertySource 迭代器
它有一個子類MutablePropertySources,你可以繼承MutablePropertySources自定義自己的PropertySources 逸邦,MutablePropertySources值得注意的是addFirst(PropertySource)和addLast(PropertySource)恩沛,這兩個方法會影響PropertyResolver的執(zhí)行,也就是說相同key的值昭雌,找到就不會在找了
PropertyResolver Property的解析器
它有個子類AbstractPropertyResolver复唤,可以解析${}占位符,當(dāng)然你也可以實現(xiàn)ConfigurablePropertyResolver自定義自己的占位符規(guī)則
Environment 表示的是當(dāng)前應(yīng)用的環(huán)境
它有個子類StandardEnvironment烛卧,集成了PropertySource 和PropertySources 和AbstractPropertyResolver佛纫,可以獲取得到系統(tǒng)的環(huán)境變量和jvm的環(huán)境變量妓局,當(dāng)然,你也可以繼承AbstractEnvironment自定義自己的Environment 呈宇,來獲取更多其他的環(huán)境變量