工做的时候,通常来讲代码都是分环境的,好比dev,test,prd什么的,在用到@PropertySource 注解的时候,发现好像不能根据环境读取自定义的.properties文件,好比我有个systemProperties-dev.properties
文件,一开始只是systemProperties-${spring.profiles.active}.properties
这样的方式勉强能用,可是后来当个人环境变量变成多环境的时候,也就是spring.profiles.active = dev,test
这样的是,这个方法就不奏效了,(多傻啊,其实早就想到了,他会直接在“-”后面拼了一个“dev,test”)而后在网上看了看资料,参考了如下的一篇文章,而后参照了下源码,用了一个比较简单,可是很难看的方法实现了:P(感受也是暂时解决问题。)。
参照文章:Springboot中PropertySource注解多环境支持以及原理java
主要思想,重写PropertySourceFactory,在PropertySourceFactory中,从新取得resource,spring
@Component @PropertySource(name="systemConfig", value = {"classpath:/systemConfig-${spring.profiles.active}.properties"}, factory = SystemPropertySourceFactory.class) public class SystemProperties { // 本身的内容.... }
这里指定了 factory = SystemPropertySourceFactory.class
,接下来ide
@Configuration public class SystemPropertySourceFactory implements PropertySourceFactory { @Override public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) throws IOException { FileSystemResourceLoader resourceLoader = new FileSystemResourceLoader(); //取得当前活动的环境名称(由于直接获取spring.profiles.active 失败,因此才把环境名称拼在文件名后面来拿) //其实感受应该有能够直接取的方法好比从环境里取 String[] actives = encodedResource.getResource().getFilename().split("\\.")[0].replace(name + "-", "").split(","); //若是只有一个,就直接返回 if (actives.length <= 1) { return (name != null ? new ResourcePropertySource(name, encodedResource) : new ResourcePropertySource(encodedResource)); } //若是是多个 List<InputStream> inputStreamList = new ArrayList<>(); String suffix = fileproperty[1]; //遍历后把全部环境的url所有抓取到list中 Arrays.stream(actives).forEach(active -> { InputStream in = this.getClass().getResourceAsStream("/" + name.concat("-" + active).concat(".").concat(suffix)); if (in != null) { inputStreamList.add(in); } }); if (resourceUrls != null && resourceUrls.size() > 0) { //串行流,将多个文件流合并车一个流 SequenceInputStream inputStream = new SequenceInputStream(Collections.enumeration(inputStreamList)); //转成resource InputStreamResource resource = new InputStreamResource(inputStream); return (name != null ? new ResourcePropertySource(name, new EncodedResource(resource)) : new ResourcePropertySource(new EncodedResource(resource))); } else { return (name != null ? new ResourcePropertySource(name, encodedResource) : new ResourcePropertySource(encodedResource)); } } }
这样实现后,就能将多个环境的Property文件加载进去了。this
而后是关于spring.profiles.active 为何要这么取,我试过@value,和用Environment 对象,都取不到,可能跟bean建立的前后顺序有关。没有继续调查,但愿知道缘由的朋友能帮忙解答~url