Spring Boot 2.4.0.M2 刚刚发布,它对 application.properties
和 application.yml
文件的加载方式进行重构。若是应用程序仅使用单个 application.properties
或 application.yml
做为配置文件,那么可能感觉不到任何区别。可是若是您的应用程序使用更复杂的配置(例如,Spring Cloud 配置中心等),则须要来了解更改的内容以及缘由。html
随着最新版本 Spring Boot 发布,Spring 一直在努力提高对 Kubernetes 的原生支持。在 Spring Boot 2.3 中,官方想增长 Kubernetes Volume 的配置支持可是未能实现。java
Volume 配置挂载是 Kubernetes 的一项经常使用功能,其中 ConfigMap
指令用于直接在文件系统上显示配置。您能够装载包含多个键和值合并的完整 YAML 文件,也可使用更简单的目录树格式,其中文件名是键,文件内容是值。git
但愿同时提供二者的支持,而且可以兼容咱们现有的 application.properties
和 application.yml
。为此须要修改 ConfigFileApplicationListener
类。github
在 Spring Boot 中配置文件加载类 ConfigFileApplicationListener
属于比较核心的底层代码,每次维护都是很是的困难。并非由于代码编写错误或者缺乏相关单元测试,而是在添加新功能时,很难解决以前存在的问题。spring
即:数据库
如下面的例子来讲:markdown
security.user.password: usera
---
spring.profiles: local
security.user.password: userb
runlocal: true
---
spring.profiles: !dev
spring.profiles.include: local
security.user.password: userc
复制代码
在这里,咱们有一个 多文档 YAML文件(一个文件由三个逻辑文档组成,由 ---
分隔)。app
若是使用 --spring.profile.actives=prod
运行,那么 security.user.password
的值是什么?是否设置 runlocal
属性?中间部分文档是否包括在内,由于配置文件在处理时没有激活?spring-boot
咱们常常会遇到关于这个文件处理逻辑的问题,可是每当试图修复它们时,最后带来各类各样的负面问题。oop
所以,在 Spring boot 2.4 中对 Properties 和 YAML 文件的加载方式进行两个重大更改:
从 Spring Boot 2.4 开始,加载 Properties 和 YAML 文件时候会遵循, 在文档中声明排序靠前的属性将被靠后的属性覆盖 。
这点与 .properties
的排序规则相同。咱们能够想想,每次将一个 Value 放入 Map
,具备相同 key 的新值放入时,将替换已经存在的 Value。
同理对 Multi-document 的 YAML 文件,较低的排序也将被较高的覆盖:
test: "value"
---
test: "overridden-value"
复制代码
Properties
文件支持多文档属性在 Spring Boot 2.4 中, Properties
支持相似 YAML 多文档功能。多文档属性文件使用注释( #
)后跟三个(---)破折号来分隔文档( 选择使用注释,以使现有的 IDE 正常支持 )。
例如,上面的 YAML 等效的 properties 为:
test=value
#---
test=overridden-value
复制代码
上述示例实际上没有任何意义,在咱们开发过程当中更为常见是声明某个属性仅在特定环境生效激活。
在 Spring Boot 2.3 中能够配置 spring.profiles
来实现。但在 Spring Boot 2.4 中 属性更改 为 spring.config.activate.on-profile
。
例如,咱们想要 test
属性仅仅在 dev
Profile 激活时覆盖它,则可使用如下配置:
test=value
#---
spring.config.activate.on-profile=dev
test=overridden-value
复制代码
使用 spring.profiles.active
属性在 application.properties
或 application.yaml
文件的 根配置文件 来激 相关环境文件。
例如,下面这样:
test=value
spring.profiles.active=local
#---
spring.config.activate.on-profile=dev
test=overridden value
复制代码
不容许的是将 spring.profiles.active
属性与 spring.config.activate.on-profile
一块儿使用。例如,如下文件将引起异常:
test=value
#---
spring.config.activate.on-profile=dev
spring.profiles.active=local # will fail
test=overridden value
复制代码
经过这一新限制能使 application.properties
和 application.yml
文件更加容易理解。使得 Spring Boot 自己更易于管理和维护。
Profile Groups 是 Spring Boot 2.4 中的一项新功能,可以让您将单个配置文件扩展为多个子配置文件。例如,假设有一组复杂的 @Configuration
类,可使用 @Profile
注释有条件地启用它们。使用 @Profile("proddb")
开启数据库配置,使用 @Profile("prodmq")
开启消息配置等等。
使用多个配置文件可使咱们的代码更易于理解,可是对于部署而言并非理想的选择。若用户须要同时激活 proddb
, prodmq
, prodmetrics
等。那么 Profile Groups 可以让您作到这一点。
您能够在 application.properties
或 application.yml
文件中定义 spring.profiles.group,那么开启 prod 则就至关于激活了此组的所有环境
。例如:
spring.profiles.group.prod=proddb,prodmq,prodmetrics
复制代码
如今,咱们已经解决了配置文件处理的基本问题,咱们终于可以考虑咱们想要提供的新功能。咱们使用 Spring Boot 2.4 提供的主要功能是支持导入其余配置。
对于早期版本的 Spring Boot,很难在 application.properties
和 application.yml
以外导入其余 properties
或 yaml
文件。可使用 spring.config.additional-location
属性但它能够处理的文件类型很是有限。
在 Spring Boot 2.4 能够直接在 application.properties
或 application.yml
文件中使用新的 spring.config.import
属性。例如但愿导入一个 "忽略的 git" 的 developer.properties
文件,以便团队中的任何开发人员均可以快速更改属性:
application.name=myapp
spring.config.import=developer.properties
复制代码
甚至能够将 spring.config.import
与 spring.config.activate.on-profile
结合起来使用。例如,这里 prod.properties
仅在 prod
配置文件处于激活状态时加载:
spring.config.activate.on-profile=prod
spring.config.import=prod.properties
复制代码
Import 能够被视为在声明它们的文档下方插入的其余文档。它们 遵循与常规多文档文件相同的自上而下的顺序:导入仅被导入一次,不管声明了多少次。
导入定义使用与 URL 同样语法做为其值。若是您的位置没有前缀,则它被视为常规文件或文件夹。可是,若是您使用 configtree:
前缀,则告诉 Spring Boot,您将指望在该位置使用 Kubernetes volume 装载的配置树。
例如,您能够在 application.properties
配置:
spring.config.import=configtree:/etc/config
复制代码
若是您有如下装载的内容:
etc/
+- config/
+- my/
| +- application
+- test
复制代码
将在 Spring Environment
中拥有 my.application
和 test
属性。 my.application
的值是 /etc/config/my/application
的内容, test
的值是 /etc/config/test
的内容。
若是只但愿 Volume 挂载的配置(或该内容的任何属性)在特 定的云平台上 处于激活状态,可使用 spring.config.activate.on-cloud-platform
属性。它的工做方式与 spring.config.activate.on-profile
相似,但它使用 CloudPlatform
的值,而不是配置文件名称。
若是咱们想要在部署到 Kubernetes 时启用上述配置树,咱们能够执行如下操做:
spring.config.activate.on-cloud-platform=kubernetes
spring.config.import=configtree:/etc/config
复制代码
spring.config.import
属性中指定的位置字符串是彻底可插拔的,能够经过编写几个自定义类来扩展,第三方库将对自定义位置提供支持。例如,你能想到的第三方 jar 文件,例如 archaius://…
, vault://…
或 zookeeper://…
。
若是您有兴趣添加其余位置支持,请查看 org.springframework.boot.context.config
包 ConfigDataLocationResolver
和 ConfigDataLoader
的 javadoc。
正如上文所描述的,Spring Boot 针对配置文件的功能变动是很是大的。考虑到低版本的兼容性
能够设置 spring.config.use-legacy-processing=true
属性便可,恢复到以前版本的文件处理机制。
若是发现关于此处的问题,则须要切换到旧版处理,请 在 GitHub 上提出问题,官方将尝试解决该问题。
官方但愿新的配置数据处理更加好用,而且不会引发太多升级麻烦。若是您想了解更多有关它们的信息,能够查阅更新的 参考文档。
欢迎关注我,后续会经过代码来详细说明此处变动。
翻译: 冷冷、如梦技术