springBoot的EnvironmentPostProcessor使用,根据生产环境,加载指定环境所有properties配置文件,并放入自定义工具类PropertiesUtil
文章目录
前言
在进行公共组件封装时 根据配置的环境,决定采用不同的配置文件,并且将其加载到自定义的PropertiesUtil工具类中
一、EnvironmentPostProcessor是什么?
SpringBoot支持动态的读取文件,留下的扩展接口org.springframework.boot.env.EnvironmentPostProcessor。这个接口是spring包下的,使用这个进行配置文件的集中管理,而不需要每个项目都去配置配置文件。这种方法也是springboot框架留下的一个扩展(可以自己去扩展)
二、使用步骤
1.实现EnvironmentPostProcessor
@Configuration
public class Configs implements EnvironmentPostProcessor, Ordered {
private static final Integer POST_PROCESSOR_ORDER = Integer.MIN_VALUE+10;
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
}
@Override
public int getOrder() {
return this.POST_PROCESSOR_ORDER+1;
}
}
1)首先,要实现springboot提供的EnvironmentPostProcessor接口,并且实现它的postProcessEnvironment方法,postProcessEnvironment就是我们具体写逻辑处理的地方。
2)同时继承spring的Ordered接口来指定优先级,因为springboot是已经有默认的实现了,我们的扩展需要在它们执行之后执行 要不然ConfigurableEnvironment 参数中有些数据是没有的。默认最后一执行的顺序是 Integer.MIN_VALUE+10,我们可以写一个静态 常量。
3)实现Ordered的getOrder方法 并 在前面定义的默认顺序加一this.POST_PROCESSOR_ORDER+1
2.读入数据
主逻辑代码:
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
MutablePropertySources propertySources = environment.getPropertySources();
//这里是获取我们指定的当前激活的配置文件
String[] profiles = environment.getActiveProfiles();
Properties prop = getConfig(profiles);
propertySources.addLast(new PropertiesPropertySource("allProp",prop));
for (PropertySource<?> propertySource : propertySources) {
//是键值对的properties 才放入propertiesUtil工具类中
if(propertySource.getSource() instanceof Map){
Map map = (Map) propertySource.getSource();
for (Object key : map.keySet()) {
//写入我们定义的工具类缓存中
PropertiesUtil.getProperties().put(keyStr, value.toString());
}
}
}
}
加载配置文件代码getConfig
private Properties getConfig(String[] profiles){
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
List<Resource> resourceList = new ArrayList<>();
getResource(resolver,resourceList,"classpath*:/*.properties");
getResource(resolver,resourceList,"classpath*:/log.config");
if(profiles!=null){
for (int i = 0; i < profiles.length; i++) {
String p = "classpath*:/config/"+profiles[i]+"/*.properties";
getResource(resolver,resourceList,p);
}
}
try {
//spring properties管理对象 将properties加载处理进ioc
PropertiesFactoryBean config = new PropertiesFactoryBean();
config.setLocations(resourceList.toArray(new Resource[]{}));
config.afterPropertiesSet();
return config.getObject();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
根据path获取Resource
private void getResource(PathMatchingResourcePatternResolver resolver,List<Resource> resourceList,String path){
try {
Resource[] resources = resolver.getResources(path);
for (Resource resource : resources) {
resourceList.add(resource);
}
} catch (IOException e) {
logger.error("",e);
}
}
3.配置进spring.factories
在resources 下 META-INF文件夹下加上 spring.factories文件,配置org.springframework.boot.env.EnvironmentPostProcessor
注意事项
在resources 下 META-INF文件夹下加上 spring.factories文件 并且将类路径配置到org.springframework.boot.env.EnvironmentPostProcessor