spring-boot-route(二)讀取配置檔案的幾種方式

Java旅途發表於2020-10-03

Spring Boot提供了兩種格式的配置檔案,分別是propertiesyml。Spring Boot最大的特點就是自動化配置,如果我們想修改自動化配置的預設值,就可以通過配置檔案來指定自己伺服器相關的引數。

配置檔案集約管理了配置資訊,如果把配置引數寫到Java程式碼中,維護起來非常不方便,如果使用配置檔案,我們可以統一管理,統一修改。我比較推薦使用yml格式的配置檔案,YAML是專門用來寫配置檔案的語言,通常以yml為字尾,它的結構非常清晰,更易於閱讀。

將自定義的配置寫在配置檔案中後,如果想要在java程式碼中使用配置,這時候就需要讀取配置檔案,讀取配置檔案的方式有三種,我們挨個介紹一下如果進行讀取!

第一種:使用@Value註解讀取

第一步:在配置檔案中增加加入以下配置

config:
  name: Java旅途
  desc: spring-boot-route

第二部:新建Java類讀取配置資訊

@RestController
public class GetValue {

    @Value("${config.name}")
    private String name;

    @Value("${config.desc}")
    private String desc;

    @GetMapping("getValue")
    public String getValue(){
        return "name="+name+";desc="+desc;
    }
}

@Value註解使用簡單,適合單個引數的注入。

第二種:使用@ConfigurationProperties讀取

@ConfigurationProperties與@Value相比,更加適合讀取陣列型別的引數。

1. 獲取單個物件

第一步:在yml檔案中新建物件型別的配置資訊

configs:
  config:
    name: Java旅途
    desc: spring-boot-route

第二步:新建實體對映配置資訊

@Component
@ConfigurationProperties(prefix = "configs.config")
@Data
public class Config {

    private String name;
    private String desc;
}

第三步:新建類測試是否獲取到引數

@RestController
public class GetConfigurationProperties {

    @Autowired
    private Config config;

    @GetMapping("/getConfig")
    public String getConfig(){
        return config.getName()+";"+config.getDesc();
    }
}

2. 獲取物件集合

第一步:在yml檔案中新建陣列型別的引數

configs:
  config:
    - name: Java旅途
      desc: spring-boot-route
    - name: javatrip
      desc: spring-boot-yml

第二步:新建實體對映配置資訊

@Component
@ConfigurationProperties(prefix = "configarr")
@Data
public class Configs {

    private List<Config> config = new ArrayList<>();

    @Data
    public static class Config{

        private String name;
        private String desc;
    }
}

第三步:新建測試類獲取引數

@RestController
public class GetConfigurationProperties {

    @Autowired
    private Configs configs;
    
    @GetMapping("/getConfigs")
    public String getConfigs(){

        String content = "";
        List<Configs.Config> configList = configs.getConfig();
        Map<String,Object> map = new HashMap<>();
        for (Configs.Config bean : configList){
            content += bean.getName()+";"+bean.getDesc()+",";
        }
        return content;
    }
}

除了上面介紹的兩種方式之外,還可以通過Spring Boot上下文的環境變數來讀取配置檔案資訊,不過上面兩種方式已經完全可以滿足所有需求,這裡就不再進行介紹了。

思考與擴充套件

如果多個配置檔案具有相同的配置資訊,那麼如何讀取特定的配置檔案資訊呢

配置檔案具有優先順序,一般情況下,yml檔案的優先順序高於properties,這樣就會導致properties的配置資訊後載入,最後讀取的時候就會properties的配置資訊的優先順序會更高。

上面介紹的兩種讀取配置檔案的方式可以和另一個註解配合使用,@PropertySource常用的三個屬性,一個是value用於指定配置檔案,另一個是encoding用於指定編碼,最後一個是factory,用於指定解析工廠。

這裡需要注意一下:@PropertySource預設只會載入properties格式的檔案,也就是我們如果指定了yml型別的檔案是不會生效的,這時候就需要我們重寫解析工廠。

先看看下預設的解析工廠原始碼:

public class DefaultPropertySourceFactory implements PropertySourceFactory {
    public DefaultPropertySourceFactory() {
    }

    public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {
        return name != null ? new ResourcePropertySource(name, resource) : new ResourcePropertySource(resource);
    }
}

自定義解析工廠,實現PropertySourceFactory

public class YmlConfigFactory extends DefaultPropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        String sourceName = name != null ? name : resource.getResource().getFilename();
        if (!resource.getResource().exists()) {
            return new PropertiesPropertySource(sourceName, new Properties());
        } else if (sourceName.endsWith(".yml") || sourceName.endsWith(".yaml")) {
            Properties propertiesFromYaml = loadYml(resource);
            return new PropertiesPropertySource(sourceName, propertiesFromYaml);
        } else {
            return super.createPropertySource(name, resource);
        }
    }

    private Properties loadYml(EncodedResource resource) throws IOException {
        YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
        factory.setResources(resource.getResource());
        factory.afterPropertiesSet();
        return factory.getObject();
    }
}

第一步:新建兩個配置檔案,test.yml和test.properties,增加以下配置資訊

spring:
  value: javatrip123
  remark: javatrip123
spring:
  value: javatrip123
  remark: javatrip123

第二步:指定配置檔案對映配置檔案內容

@Data
@Configuration
@PropertySource(value = {"classpath:test.yml"},encoding = "gbk")
@ConfigurationProperties(prefix = "spring")
public class Spring {

    private String value;
    private String remark;
}

第三步:新建類進行測試

@RestController
public class GetSource {

    @Autowired
    private Spring spring;

    @GetMapping("get")
    public String getSource(){
        return spring.getRemark()+";"+spring.getValue();
    }
}

此是spring-boot-route系列的第二篇文章,這個系列的文章都比較簡單,主要目的就是為了幫助初次接觸Spring Boot 的同學有一個系統的認識。本文已收錄至我的github,歡迎各位小夥伴star

githubhttps://github.com/binzh303/spring-boot-route

點關注、不迷路

如果覺得文章不錯,歡迎關注點贊收藏,你們的支援是我創作的動力,感謝大家。

如果文章寫的有問題,請不要吝嗇,歡迎留言指出,我會及時核查修改。

如果你還想更加深入的瞭解我,可以微信搜尋「Java旅途」進行關注。回覆「1024」即可獲得學習視訊及精美電子書。每天7:30準時推送技術文章,讓你的上班路不在孤獨,而且每月還有送書活動,助你提升硬實力!

相關文章