Spring Boot @PropertySource 加載指定yaml配置文件獲取不到配置的解決方法
@PropertySource可用於加載指定的配置文件,可以是properties配置文件,也可以是yml、yaml配置文件。
加載properties配置文件:
@Component
@PropertySource(value = {"classpath:person.properties"})
@ConfigurationProperties(prefix = "person")
public class Person {
// @Value("${person.last-name}")
private String lastName;
private Integer age;
private Boolean boss;
private Date birth;
}
打印結果:Person{lastName='Jerry', age=25, boss=true, birth=Sat Dec 12 00:00:00 CST 2020, maps={k1=haha, k2=hehe}, lists=[a, b, c, d], dog=Dog{name='狗子', age=12}}
測試之后,可以正常獲取到properties配置文件中的內容。
但加載yml配置文件的時候,則會出現獲取不到屬性的問題:
@Component
@PropertySource(value = {"classpath:person.yaml"})
@ConfigurationProperties(prefix = "person")
public class Person {
private String lastName;
private Integer age;
private Boolean boss;
private Date birth;
打印結果:Person{lastName='null', age=null, boss=null, birth=null, maps=null, lists=null, dog=null}
所有屬性值都為空,顯然是沒有讀取到配置文件。
解決方法:
@PropertySource 的注解中,有一個factory屬性,可指定一個自定義的PropertySourceFactory接口實現,用於解析指定的文件。默認的實現是DefaultPropertySourceFactory,繼續跟進,使用了PropertiesLoaderUtils.loadProperties進行文件解析,所以默認就是使用Properties進行解析的。
可以寫一個類繼承DefaultPropertySourceFactory
,然后重寫createPropertySource()
:
public class YamlAndPropertySourceFactory extends DefaultPropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
if (resource == null) {
return super.createPropertySource(name, resource);
}
Resource resourceResource = resource.getResource();
if (!resourceResource.exists()) {
return new PropertiesPropertySource(null, new Properties());
} else if (resourceResource.getFilename().endsWith(".yml") || resourceResource.getFilename().endsWith(".yaml")) {
List<PropertySource<?>> sources = new YamlPropertySourceLoader().load(resourceResource.getFilename(), resourceResource);
return sources.get(0);
}
return super.createPropertySource(name, resource);
}
}
使用的時候加上factory屬性,屬性值為YamlAndPropertySourceFactory.class
@Component
@PropertySource(value = {"classpath:person.yaml"},factory = YamlAndPropertySourceFactory.class)
@ConfigurationProperties(prefix = "person")
public class Person {
private String lastName;
private Integer age;
private Boolean boss;
private Date birth;
}
再次測試:
打印結果:Person{lastName='法外狂徒張三', age=25, boss=true, birth=Sat Dec 12 00:00:00 CST 2020, maps={friend1=lisi, friend2=wangwu, friend3=zhaoliu}, lists=[haha, hehe, xixi, hiahia], dog=Dog{name='阿黃', age=12}}
發現可以正常獲取到yml配置文件中的屬性值了。