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/