@PropertySource 分環境讀取配置

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

SystemProperties.java


@Component
@PropertySource(name="systemConfig", value = {"classpath:/systemConfig-${spring.profiles.active}.properties"}, factory = SystemPropertySourceFactory.class)
public class SystemProperties {
    // 本身的內容.... 
}

這裏指定了 factory = SystemPropertySourceFactory.class,接下來ide

SystemPropertySourceFactory.java


@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

相關文章
相關標籤/搜索