SpringBoot配置文件@PropertySource 同时支持properties文件与yaml(yml)
程序员文章站
2022-05-02 12:14:18
...
Yaml(yml)
最近比较流行的配置文件,相对properties,配置文件结构更清晰简洁.前段时间项目需要引入的配置,于是想用yml
文件来增加新的属性配置,新增属性放在application.yml
中是没问题的,但是放其他文件中,然后通过@PropertySource
引入时,却出现了问题,所有.yml
中的参数配置全部读取无效,properties文件是正常的,后来在*上看到@PropertySource
中存在factory
参数,通过配置factory
参数可以达到我们想要的效果。@PropertySource factory
属性的factory
默认配置是Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;
, 我们再看下PropertySourceFactory
的源码就可知道了,
/**
* Strategy interface for creating resource-based {@link PropertySource} wrappers.
*
* @author Juergen Hoeller
* @since 4.3
* @see DefaultPropertySourceFactory
*/
public interface PropertySourceFactory {
/**
* Create a {@link PropertySource} that wraps the given resource.
* @param name the name of the property source
* @param resource the resource (potentially encoded) to wrap
* @return the new {@link PropertySource} (never {@code null})
* @throws IOException if resource resolution failed
*/
PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException;
}
默认实现是DefaultPropertySourceFactory
,
/**
* The default implementation for {@link PropertySourceFactory},
* wrapping every resource in a {@link ResourcePropertySource}.
*
* @author Juergen Hoeller
* @since 4.3
* @see PropertySourceFactory
* @see ResourcePropertySource
*/
public class DefaultPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
return (name != null ? new ResourcePropertySource(name, resource) : new ResourcePropertySource(resource));
}
}
我们所有做的只需继承DefaultPropertySourceFactory,然后对createPropertySource作下微调,就可以支持yaml了.
public class MixPropertySourceFactory 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();
}
}
这里做了个简单的文件后缀判断,如果是以.yml或.yaml结尾,则通过YamlPropertiesFactoryBean加载,其他情况则采用默认方式加载.如果大家需要支持json或xml等其他格式,也可在这里自动加入策略处理.
最后在SpringApplication上加入配置
@PropertySource(value = {
"a.properties",
"b.yml"
}, factory = MixPropertySourceFactory.class)
就可以了