工做的時候,通常來講代碼都是分環境的,好比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