spring-boot-route(二)讀取配置文件的幾種方式
- 2020 年 10 月 3 日
- 筆記
- spring-boot-route
Spring Boot提供了兩種格式的配置文件,分別是properties 和 yml。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!
github://github.com/binzh303/spring-boot-route
點關注、不迷路
如果覺得文章不錯,歡迎關注、點贊、收藏,你們的支援是我創作的動力,感謝大家。
如果文章寫的有問題,請不要吝嗇,歡迎留言指出,我會及時核查修改。
如果你還想更加深入的了解我,可以微信搜索「Java旅途」進行關注。回復「1024」即可獲得學習影片及精美電子書。每天7:30準時推送技術文章,讓你的上班路不在孤獨,而且每月還有送書活動,助你提升硬實力!


