踩过的一个坑
记得之前曾经总结过一篇文章:Springboot中yml文件读取。 在一个modul下新建配置yml配置文件,esb-pool-config.yml:
# esb服务同步池配置
sapConfig:
DBCHNESBCFG:
type: sc
name: 自由电渠
hibernate: hibernate.cfg.busa.xml
esb: 10.113.161.11:51000
DBCHNESBBJ:
type: sc
name: 北京环境
hibernate: todo.xml
esb: 172.18.231.104:51000
DBCHNESBBJ1:
type: fb
name: 北京发布环境2
hibernate: todo1.xml
esb: 172.18.231.104:51000
而后按部就班在bean里面引用里面的配置:
@Component
@PropertySource("classpath:esb-pool-config.yml")
@ConfigurationProperties
public class EsbPoolConfig {
/**
* 配置文件里面的配置,默认会全部加载到里面来的
*/
private Map<String,Entry> sapConfig = new HashMap<>();
// getter settter方法
}
结果发现根本就读取不到配置,sapConfig一直empty。 有点懵。 然后把上述配置写在程序启动的application.yml配置文件里面的,bean却能读到这些配置。 然后更懵了。
开始有点怀疑是否是@PropertySource
注解的问题,根本就没有读到我自定义的yml配置文件。
看了下@PropertySource
注解的文档,发现其只支持*.properties格式的配置文件。
有点无语。
然后尝试将上述yml配置文件该为properties配置文件:
sap.sapConfig.DBCHNESBCFG.type=sc
sap.sapConfig.DBCHNESBCFG.name=自由电渠
sap.sapConfig.DBCHNESBCFG.hibernate=hibernate.cfg.busa.xml
sap.sapConfig.DBCHNESBCFG.esb=10.113.161.11:51000
sap.sapConfig.DBCHNESBBJ.type=sc
sap.sapConfig.DBCHNESBBJ.name=北京环境
sap.sapConfig.DBCHNESBBJ.hibernate=todo.xml
sap.sapConfig.DBCHNESBBJ.esb=172.18.231.104:51000
sap.sapConfig.DBCHNESBBJ1.type=fb
sap.sapConfig.DBCHNESBBJ1.name=北京发布环境1
sap.sapConfig.DBCHNESBBJ1.hibernate=todo1.xml
sap.sapConfig.DBCHNESBBJ1.esb=172.18.231.104:51000
启动工程,bean读取到了properties配置文件里面的配置了。
解决
貌似问题已经解决了,其实并不然。由于properties的格式远不如yml配置的清晰,我还是尝试下能否继续使用PropertySource来加载yml配置文件。
PropertySource注解中有一个参数:factory
,可以指定PropertySourceFactory
,通过PropertySourceFactory可以指定加载配置文件的方式。
于是一个实现了简单的可以加载yml的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());
}
if (sourceName.endsWith(".yml") || sourceName.endsWith(".yaml")) {
//yml这里手动加进去
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(resource.getResource());
factory.afterPropertiesSet();
Properties propertiesFromYaml = factory.getObject();
return new PropertiesPropertySource(sourceName, propertiesFromYaml);
}
return super.createPropertySource(name, resource);
}
}
而后,在上述bean里面引入该factory:
@Component
@PropertySource(value = "classpath:esb-pool-config.yml",factory = YmlConfigFactory.class)
@ConfigurationProperties
public class EsbPoolConfig {
/**
* 配置文件里面的配置,默认会全部加载到里面来的
*/
private Map<String,Entry> sapConfig = new HashMap<>();
// getter settter方法
}
于是,问题得到解决。PropertySource也能加载yml配置文件了。
总结
默认的PropertySource
是不支持加载yml/yaml等配置文件的,它默认只会加载properties配置文件。通过实现PropertySourceFactory
接口,然后在注解的factory属性指定,可以自定义加载配置文件的方式。当然,也不仅仅只是yml,其他的配置方式,只要最后能够支持封装成Properties
对象,都可以应用到。
发表评论