上来先来个例子
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);
//需要解析器,自定义的解析器,你可以选择实现PropertySourcesPropertyResolver 或者AbstractPropertyResolver
//PropertySourcesPropertyResolver propertySourcesPropertyResolver = new PropertySourcesPropertyResolver(propertySources);
class MyPropertySourcesPropertyResolver extends PropertySourcesPropertyResolver{
public MyPropertySourcesPropertyResolver(PropertySources propertySources) {
super(propertySources);
}
//没必要实现
@Override
protected String getPropertyAsRawString(String key) {
return super.getPropertyAsRawString(key);
}
//没必要实现
@Override
protected <T> T getProperty(String key, Class<T> targetValueType, boolean resolveNestedPlaceholders) {
return super.getProperty(key, targetValueType, resolveNestedPlaceholders);
}
}
//自定义加载系统的环境变量进来,也可以加载其他的环境变量
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的属性值得关注,
name可以说名是哪一个配置文件,source就是配置文件的内容,比如MapPropertySource的name是字符串
source就是Map<String,Object>,还有就是可以PropertySource.getProperty(“配置文件内容中的key”)得到配置文件内容中的value
PropertySources 其实就是一个PropertySource 迭代器
它有一个子类MutablePropertySources,你可以继承MutablePropertySources自定义自己的PropertySources ,MutablePropertySources值得注意的是addFirst(PropertySource)和addLast(PropertySource),这两个方法会影响PropertyResolver的执行,也就是说相同key的值,找到就不会在找了
PropertyResolver Property的解析器
它有个子类AbstractPropertyResolver,可以解析${}占位符,当然你也可以实现ConfigurablePropertyResolver自定义自己的占位符规则
Environment 表示的是当前应用的环境
它有个子类StandardEnvironment,集成了PropertySource 和PropertySources 和AbstractPropertyResolver,可以获取得到系统的环境变量和jvm的环境变量,当然,你也可以继承AbstractEnvironment自定义自己的Environment ,来获取更多其他的环境变量