文章图片
欢迎加入 Spring cloud 交流群: 617143034
文章目录
- 简介
- 为什么我们要进行这些更改
- ConfigFileApplicationListener 的问题
- 文档顺序
- 多文档 Properties 文件
- 特定配置文件的专有属性
- 配置文件激活过程
- 配置文件组 (profile group)
- 导入其他配置
- 卷挂载的配置树
- 云平台激活过程
- 支持额外的位置
- 继续使用旧版处理方式
- 摘要
- 推广
简介 原文发布于: https://spring.io/blog/2020/08/14/config-file-processing-in-spring-boot-2-4
Spring Boot 2.4.0.M2 刚刚发布,它对
application.properties
和 application.yml
文件的加载方式进行了一些有趣的更改。如果您的应用程序使用仅使用单个
application.properties
或 application.yml
文件,那么您可能不会注意到任何区别。但是,如果您的应用程序使用更复杂的设置(例如,针对特定配置文件的属性),则可能需要继续阅读以了解我们所做的更改以及更改的原因。为什么我们要进行这些更改 借助最新版本的 Spring Boot,我们一直在努力改善对 Kubernetes 的支持。我们想在 Spring Boot 2.3 中添加但没能做到的一件事是对卷挂载 (volume mount) 配置的支持。
卷挂载配置是 Kubernetes 的一项常用功能,其中的
ConfigMap
指令用于直接在文件系统上显示配置。您可以载入包含多个键值对的完整 YAML 文件,也可以使用更简单的目录树格式,其中文件名是键,文件的内容是值。我们想为两者都提供支持,并且以一种可以与现有的
application.properties
和 application.yml
一起使用的方式进行实现。为此,我们需要修改令人??恐惧的ConfigFileApplicationListener
类。ConfigFileApplicationListener 的问题 几年前,视频游戏《Trap Adventure 2》中的一些集锦 (Youtube) 开始出现。它们与软件中可能发生的事情非常相似:有时,您会发现自己被难以更改的代码包围。在 Spring Boot 中,
ConfigFileApplicationListener
最终成为这些了 “陷阱” 之一。(译者注: 《Trap Adventure 2》是一种类似于 《I wanna》的跳刺游戏)
它并不是代码编写错误或缺少测试。只是在我们添加功能时陷入了困境。
现有的代码有两个主要问题与配置文件有关(主要在 YAML 中)。即:
- 您可以从一个配置文件中启用其他配置文件。
- 很难知道配置确切的添加顺序。
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 文件(一个文件,其中包含由分隔符 ‘—’ 进行分隔的三个逻辑文档)。
如果您使用
--spring.profiles.active=prod
启动应用, 那 security.user.password
的值究竟是什么?runlocal
属性被设置了么?你确定?如果配置文件在被处理时未被激活, 中间部分的逻辑文档也会被包含在内么?我们经常会遇到此类文件处理逻辑的问题,但是每当我们尝试修复它时,总会遇到不兼容的情况。我们最终决定前进的唯一方法是重新考虑整个加载过程。
因此,在 Spring Boot 2.4 中,我们计划对属性和 YAML 文件的加载方式进行两项重大更改:
- 文档将按照定义的顺序加载。
- 不能再从配置文件的文档中激活其他配置文件。
这与过去 Properties 文件使用的排序规则相同。你可以试想一下将每行当作一个条目 (
entry
) 放入 Map
中。当有相同键的新值放入时,现有的条目将被替换掉。遵循这些规则,对于给定的多文档 YAML 文件,靠文件底部的文档将覆盖靠文件顶部的文档:
test:"value"
---
test:"overridden-value"
多文档 Properties 文件 借助 Spring Boot 2.4,我们决定将类似 YAML 的多文档支持引入到 Java 的 Properties 文件中。多文档 Properties 文件将使用注释(#)后跟着三个破折号来分隔文档(使用注释是为了使现有的 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
配置文件处于激活状态时被覆盖,则可以使用以下命令:test=value
#---
spring.config.activate.on-profile=dev
test=overridden-value
配置文件激活过程 您仍然可以在
application.properties
或 application.yaml
文件的中使用 spring.profiles.active
属性来激活或包括其他配置文件。例如,以下内容完全符合规范:
test=value
spring.profiles.active=local
#---
spring.config.activate.on-profile=dev
test=overridden-value
该属性禁止与
spring.config.activate.on-profile
结合使用。例如,以下配置将引发异常:test=value
#---
spring.config.activate.on-profile=dev
spring.profiles.active=local #此处将导致应用启动失败
test=overridden-value
我们希望这一新限制最终将使您的
application.properties
和 application.yml
文件更易于推理和理解。我们还希望它可以使 Spring Boot 本身更易于管理和维护。目前,我们知道至少有一个有效的使用场景,就是人们希望将一个配置文件扩展为多个子配置文件。为了支持这一点,我们添加了一个称为 “配置文件组(profile group)” 的功能。配置文件组 (profile group) 配置文件组是 Spring Boot 2.4 中的一项新功能,可让您将单个配置文件扩展为多个子配置文件。例如,假设您有一组复杂的
@Configuration
类,可以使用 @Profile
注释有条件地启用它们。您可能有使用 @Profile("proddb")
进行激活的数据库配置, 使用 @Profile("prodmq")
进行激活的消息配置等等。使用多个离散的配置文件可能使您的代码更易于推理,但是对于部署而言,它并不是理想的选择。你不希望强迫用户记住他们必须同时激活
proddb
,prodmq
,prodmetrics
等配置。相反,您只希望他们能够激活一个 prod
配置文件。而群组可让您做到这一点。要定义组,您可以在
application.properties
或 application.yml
中定义 spring.profiles.group
属性。例如:spring.profiles.group.prod=proddb,prodmq,prodmetrics
导入其他配置 现在,我们已经解决了配置文件处理的基本问题,我们终于可以考虑要提供的新功能。我们将在 Spring Boot 2.4 中提供的主要功能是对导入其他配置的支持。
与早期版本的 Spring Boot 的,想要在
application.properties
和 application.yml
之上导入附加 Properties 或 YAML 文件是十分困难的。您可以使用 spring.config.additional-location
属性,但是您需要尽早的设置它,并且它可以处理的文件类型非常有限。在最新的里程碑版本中,您可以直接在
application.properties
或 application.yml
文件中使用新属性 spring.config.import
。例如,您可能想导入一个不受版本控制的 developer.properties
配置文件,以便您团队中的任何开发人员都可以快速更改属性:application.name=myapp
spring.config.import =developer.properties
您甚至可以将
spring.config.import
声明与 spring.config.activate.on-profile
属性结合起来。例如,仅在 prod
配置文件处于激活状态时才加载 prod.properties
文件:spring.config.activate.on-profile=prod
spring.config.import=prod.properties
导入可以被视为在声明它们的文档最底部插入的其他文档。它们遵循与常规多文档文件相同的自上而下的加载顺序:无论声明了多少次, 文件仅被导入一次。
卷挂载的配置树 导入使用类似 URL 的语法作为其值的定义。如果您指定的位置 (location) 没有前缀,那么它将被视为常规文件或文件夹。但是,如果使用
configtree:
前缀,那么 Spring Boot 将希望在该位置找到一个 Kubernetes 风格的卷挂载的配置树。例如,您可以在
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
文件中的内容。云平台激活过程 如果只希望在特定的云平台上激活卷挂载的配置树(或与此有关的任何属性),则可以使用
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
类的文档。继续使用旧版处理方式 如果您要升级现有的 Spring Boot 应用程序,而对所有这些新功能都不满意,则可以切换回旧的处理方式。为了做到这一点,你可以在
application.properties
或 application.yml
文件中设置 spring.config.use-legacy-processing=true
。这样的话您应该能获得与Spring Boot 2.3 应用程序相同的应用程序配置处理方式。如果您发现我们错过了特定的使用场景,则不得不切换到旧版处理方式,请在 GitHub 上提出一个问题,我们将尝试解决该问题。
摘要 我们希望新的配置数据处理类有用,并且不会引起太多的升级麻烦。如果您想了解更多有关它们的信息,可以查阅最新的参考文档。
推广 欢迎加入 Spring cloud 交流群: 617143034
【Spring|[Spring] Spring boot 2.4 配置文件加载流程变更】欢迎大家使用 阿里云优惠券, 新购续费更优惠:
文章图片
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- =======j2ee|spring用注解实现注入的@resource,@autowired,@inject区别
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])