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配置文件中的属性值了。