SpringBoot系列——加載自定義配置文件


  前言

  SpringBoot啟動時默認加載bootstrap.propertiesbootstrap.yml(這兩個優先級最高)、application.propertiesapplication.yml,如果我們配置了spring.profiles,同時會加載對應的application-{profile}.propertiesapplication-{profile}.yml,profile為對應的環境變量,比如dev,如果沒有配置,則會加載profile=default的配置文件

  雖然說配置項都寫在同一個配置文件沒有問題,但我們仍然希望能分開寫,這樣比較清晰,比如eureka的配置寫在eureka.properties,數據庫相關的配置寫在datasource.properties等等,因此就需要設置加載外部配置文件

  更多關於配置項信息請看官網:https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#boot-features-external-config

  本文記錄SpringBoot加載自定義配置文件的兩個方法

 

  兩種方法

  方法一

  直接在具體的類上面使用注解加載

  比如當你在ServiceAImpl需要使用到xxx.properties時

//手動加載自定義配置文件
@PropertySource(value = {
        "classpath:xxx.properties",
}, encoding = "utf-8")
@Service
public class ServiceAImpl{

    @Value("${cn.huanzi.qch.xxx}")
    private String xxx;

}

  如果你需要在更早一點引入,則可以在啟動類上進行引入

//手動加載自定義配置文件
@PropertySource(value = {
        "classpath:xxx.properties",
        "classpath:yyy.properties",
        "classpath:zzz.yml",
}, encoding = "utf-8")

@Component
@SpringBootApplication
public class SpringbootLoadmyprofilesApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootLoadmyprofilesApplication.class, args);
    }

    @Value("${cn.huanzi.qch.xxx}")
    private String xxx;

    @Value("${cn.huanzi.qch.yyy}")
    private String yyy;

    @Value("${cn.huanzi.qch.zzz}")
    private String zzz;

    @Bean
    void index(){
        System.out.println(xxx);
        System.out.println(yyy);
        System.out.println(zzz);
    }
}

  如果我們只是在業務中需要用到自定義配置文件的值,這樣引入並沒有什么問題,但外部配置是一些啟動項,SpringBoot官網並不推薦我們這樣干

  雖然在@SpringBootApplication上使用@PropertySource似乎是在環境中加載自定義資源的一種方便而簡單的方法,但我們不推薦使用它,因為SpringBoot在刷新應用程序上下文之前就准備好了環境。使用@PropertySource定義的任何鍵都加載得太晚,無法對自動配置產生任何影響。

  這種情況下需要采用第二種方法

 

  方法二

  自定義環境處理類,在啟動之前定制環境或應用程序上下文,

  Customize the Environment or ApplicationContext Before It Starts:https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#howto-customize-the-environment-or-application-context

  官網還提供了一個列子:

 

   我們也來寫一個自定義環境處理,在運行SpringApplication之前加載任意配置文件到Environment環境中

package cn.huanzi.qch.springbootloadmyprofiles;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.util.Properties;

/**
 自定義環境處理,在運行SpringApplication之前加載任意配置文件到Environment環境中
 */
public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {

    //Properties對象
    private final Properties properties = new Properties();

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment,SpringApplication application) {
        //自定義配置文件
        String[] profiles = {
                "xxx.properties",
                "yyy.properties",
                "zzz.yml",
        };

        //循環添加
        for (String profile : profiles) {
            //從classpath路徑下面查找文件
            Resource resource = new ClassPathResource(profile);
            //加載成PropertySource對象,並添加到Environment環境中
            environment.getPropertySources().addLast(loadProfiles(resource));
        }
    }

    //加載單個配置文件
    private PropertySource<?> loadProfiles(Resource resource) {
        if (!resource.exists()) {
            throw new IllegalArgumentException("資源" + resource + "不存在");
        }
        try {
            //從輸入流中加載一個Properties對象
            properties.load(resource.getInputStream());
            return new PropertiesPropertySource(resource.getFilename(), properties);
        }catch (IOException ex) {
            throw new IllegalStateException("加載配置文件失敗" + resource, ex);
        }
    }
}

  並且在META-INF/spring.factories中

#啟用我們的自定義環境處理類
org.springframework.boot.env.EnvironmentPostProcessor=cn.huanzi.qch.springbootloadmyprofiles.MyEnvironmentPostProcessor

 

   簡單測試

  先看一下我們的工程結構

  xxx、yyy、zzz里面就只有一個值(yyy、zzz就對應改成yyy、zzz)

cn.huanzi.qch.xxx=this is xxx

 

  如果不手動加載自定義配置文件,啟動將會報錯

 

  因為我們這里不是啟動項,方法一、方法二啟動效果都差不多

 

 

  后記

  部分代碼參考:https://www.jianshu.com/p/7ab1a62b04ed?from=timeline

 

  代碼開源

  代碼已經開源、托管到我的GitHub、碼雲:

  GitHub:https://github.com/huanzi-qch/springBoot

  碼雲:https://gitee.com/huanzi-qch/springBoot


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM