新增属性放在application.yml中是没问题的,但是放其他文件中,然后通过@PropertySource 引入时,会读取不到。yaml中的参数配置全部读取无效,@PropertySource 引入的properties文件是正常的。
@PropertySource中存在factory参数,通过配置factory参数可以达到我们想要的效果。
@PropertySource factory属性的factory默认配置是Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;
public interface PropertySourceFactory {
PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException;
}
默认实现是DefaultPropertySourceFactory,
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 MyPropertySourceFactory 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 = { "my.properties","my.yml"}, factory = MyPropertySourceFactory.class)