PropertySource 注解读取 Yaml 配置文件
Spring 中常用 @PropertySource
注解来加载指定配置文件,但是 @PropertySource
注解也有一些限制,如:
- 无法加载 Yaml 格式的配置
- 配置的文件不支持 profile active 配置
本文将通过扩展的方式解决以上的需求。
@PropertySource
注解不支持 Yaml 格式的配置文件
为什么不支持
我们先看一下 @PropertySource
注解的声明(以下删去了其它无关代码,只截取了关键部分)。
1 | public PropertySource { |
@PropertySource
注解的 factory
属性用于配置 PropertySource
对象的生成方式。在末配置的情况下,默认使用 PropertySourceFactory
。
再来看 ConfigurationClassParser
类中的 processPropertySource
方法,该方法用于处理 Configuration 类上的 @PropertySource
注解。
当注解上的 factory
属性为 PropertySourceFactory.class
时使用默认的 DefaultPropertySourceFactory
工厂类来生成 PropertySource
对象。
1 | // org.springframework.context.annotation.ConfigurationClassParser.java |
DefaultPropertySourceFactory
类很简单,默认的工厂方法直接将传过来的 Resource 交给 ResourcePropertySource
处理,而 ResourcePropertySource
类
只能处理 .properties
和 .xml
类型的文件。
1 | public class DefaultPropertySourceFactory implements PropertySourceFactory { |
扩展支持
经过以上分析就可以看出,只用简单的实现 PropertySourceFactory
或继承 DefaultPropertySourceFactory
,返回支持 Yaml 配置文件格式的 PropertySource
类既可。
Spring Boot 自带了一些 PropertySourceLoader
用于加载配置文件并产生 PropertySource
对象。所以我们的 Factory 类只用将生成 PropertySource
对象
的操作委托给 YamlPropertySourceLoader
类既可,完整实现如下。
1 | public class YamlPropertyLoaderFactory extends DefaultPropertySourceFactory { |
配置的文件不支持 profile active 配置
正常我们生产环境会使用另一套和开发环境不一致的配置,一般会通过设计 spring.profile.active
环境变量来启用,这样我们可以根据不同环境启用不同
配置。
如生产设置 spring.profile.active=prd
则 application.yaml
和 application-prd.yaml
都生效。但该环境变量是不在使用 @PropertySource
加载的配置文件上生效的。
1 |
|
怎样才能使 sdk.yaml
和 sdk-prd.yaml
同时加载呢?这里有个不是很完美的方法可以实现。
1 |
|
通过使用 @PropertySources
注解,同时配置两个 @PropertySource
,并让第二个 @PropertySource
配置可以在资源找不到时不报错。同时在@PropertySource
的 value
中可以使用属性占位符,动态加载 spring.profiles.active
变量指定的配置。
通过这样的方式,基本实现了需求,但还是有些问题:
- 每个配置文件都需要配置多个
spring.profiles.active
配置了多个时不可用
所以这种解决方案有得有失,有更好的方法欢迎告诉我。
PropertySource 注解读取 Yaml 配置文件
https://blog.imoe.tech/2019/08/22/20-PropertySource-annotation-read-yaml-property-file/