让@PropertySource支持Yaml
在某些特定的场景下,需要指定配置文件,而@PropertySource默认是不支持Yaml类型的配置文件的,因此,在这种情况下,通常只能将Yaml文件改写为properties文件来让@PropertySource识别。这里介绍一种方式来让@PropertySource支持Yaml格式的文件。
我们用一个测试环境的数据库连接配置文件进行测试:
spring:
datasource:
dynamic:
primary: source
strict: true
datasource:
source:
url: jdbc:sqlserver://10.177.49.98:1433;DatabaseName=SFCTEST
username: sa
password: sadjaslds
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
center:
url: jdbc:sqlserver://10.177.49.98:1433;DatabaseName=CentralDatabase
username: sa
password: jsdabajkdasd
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
首先来看默认的@PropertySource和@Value搭配读取指定Yaml文件的场景:
@Configuration
@PropertySource(value = "classpath:application-transfer.yml")
public class DruidConfig {
@Value("${spring.datasource.dynamic.datasource.source.url}")
private String sourceUrl;
@Value("${spring.datasource.dynamic.datasource.source.username}")
private String sourceUsername;
@Value("${spring.datasource.dynamic.datasource.source.password}")
private String sourcePassword;
@Value("${spring.datasource.dynamic.datasource.source.driver-class-name}")
private String sourceDriverClassName;
@Value("${spring.datasource.dynamic.datasource.center.url}")
private String centerUrl;
@Value("${spring.datasource.dynamic.datasource.center.username}")
private String centerUsername;
@Value("${spring.datasource.dynamic.datasource.center.password}")
private String centerPassword;
@Value("${spring.datasource.dynamic.datasource.center.driver-class-name}")
private String centerDriverClassName;
如果直接这样写,在启动的时候会抛出如下异常:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'druidConfig': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.datasource.dynamic.datasource.source.url' in value "${spring.datasource.dynamic.datasource.source.url}"
意思就是,解析不到这个spring.datasource.dynamic.datasource.source.url占位符所指定的值,而在上述Yaml文件中,很明显是有值的。这里的原因就在于,@PropertySource默认不支持Yaml文件,因此,读取的是默认配置文件,自然读取不到。
接下来做一些改造。我们需要一个新的propertySource工厂类,继承默认的DefaultPropertySourceFactory,实现Yaml的解析:
package com.aac.config.transfer;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;
import java.io.IOException;
import java.util.List;
public class YamlPropertySourceFactory extends DefaultPropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
List<PropertySource<?>> sources = new YamlPropertySourceLoader().load(resource.getResource().getFilename(),resource.getResource());
return sources.get(0);
}
}
在这个新的工厂类中,重写createPropertySource方法,通过YamlPropertySourceLoader加载对应的yml文件,并返回解析之后的PropertySource对象。
而后,在需要支持Yaml读取的@PropertySource注解上指定factory即可,例如:
@PropertySource(value = "classpath:application-transfer.yml", factory = YamlPropertySourceFactory.class)
即可完成正常的属性注入,如图:

浙公网安备 33010602011771号