浅谈SpringBoot2.4 配置文件加载机制大变化
前言
SpringBoot2.4.0.M2刚刚发布,它对application.properties和application.yml文件的加载方式进行重构。如果应用程序仅使用单个application.properties或application.yml作为配置文件,那么可能感受不到任何区别。但是如果您的应用程序使用更复杂的配置(例如,SpringCloud配置中心等),则需要来了解更改的内容以及原因。
为什么要进行这些更改
随着最新版本SpringBoot发布,Spring一直在努力提升对Kubernetes的原生支持。在SpringBoot2.3中,官方增加KubernetesVolume的配置支持,但是未能实现。
Volume配置挂载是Kubernetes的一项常用功能,其中ConfigMap指令用于直接在文件系统上显示配置。您可以装载包含多个键和值合并的完整YAML文件,也可以使用更简单的目录树格式,其中文件名是键,文件内容是值。
希望同时提供两者的支持,并且能够兼容我们现有的application.properties和application.yml。为此需要修改ConfigFileApplicationListener类。
ConfigFileApplicationListener问题
在SpringBoot中配置文件加载类ConfigFileApplicationListener属于比较核心的底层代码,每次维护都是非常的困难。并不是因为代码编写错误或者缺少相关单元测试,而是在添加新功能时,很难解决之前存在的问题。
即:
- 配置文件非常灵活,可以在当前文件启用其他配置文件。
- 文档加载顺序不固定。
以下面的例子来说:
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.profile.actives=prod运行,那么security.user.password的值是什么?是否设置runlocal属性?中间部分文档是否包括在内,因为配置文件在处理时没有激活?
我们经常会遇到关于这个文件处理逻辑的问题,但是每当试图修复它们时,最后带来各种各样的负面问题。
因此,在Springboot2.4中对Properties和YAML文件的加载方式进行两个重大更改:
- 文档将按定义的顺序加载。
- profiles激活开关不能被配置在特定环境中。
文档排序
从SpringBoot2.4开始,加载Properties和YAML文件时候会遵循,在文档中声明排序靠前的属性将被靠后的属性覆盖。
这点与.properties的排序规则相同。我们可以想一想,每次将一个Value放入Map,具有相同key的新值放入时,将替换已经存在的Value。
同理对Multi-document的YAML文件,较低的排序也将被较高的覆盖:
test:"value" --- test:"overridden-value"
Properties文件支持多文档属性
在SpringBoot2.4中,Properties支持类似YAML多文档功能。多文档属性文件使用注释(#)后跟三个(---)破折号来分隔文档(选择使用注释,以使现有的IDE正常支持)。
例如,上面的YAML等效的properties为:
test=value #--- test=overridden-value
特定环境激活配置
上述示例实际上没有任何意义,在我们开发过程中更为常见是声明某个属性仅在特定环境生效激活。
在SpringBoot2.3中可以配置spring.profiles来实现。但在SpringBoot2.4中属性更改为spring.config.activate.on-profile。
例如,我们想要test属性仅仅在devProfile激活时覆盖它,则可以使用以下配置:
test=value #--- spring.config.activate.on-profile=dev test=overridden-value
ProfileActivation
使用spring.profiles.active属性在application.properties或application.yaml文件的根配置文件来激相关环境文件。
例如,下面这样:
test=value spring.profiles.active=local #--- spring.config.activate.on-profile=dev test=overriddenvalue
不允许的是将spring.profiles.active属性与spring.config.activate.on-profile一起使用。例如,以下文件将引发异常:
test=value #--- spring.config.activate.on-profile=dev spring.profiles.active=local#willfail test=overriddenvalue
通过这一新限制能使application.properties和application.yml文件更加容易理解。使得SpringBoot本身更易于管理和维护。
ProfileGroups
ProfileGroups是SpringBoot2.4中的一项新功能,可让您将单个配置文件扩展为多个子配置文件。例如,假设有一组复杂的@Configuration类,可以使用@Profile注释有条件地启用它们。使用@Profile("proddb")开启数据库配置,使用@Profile("prodmq")开启消息配置等等。
使用多个配置文件可以使我们的代码更易于理解,但是对于部署而言并不是理想的选择。若用户需要同时激活proddb,prodmq,prodmetrics等。那么ProfileGroups可让您做到这一点。
您可以在application.properties或application.yml文件中定义spring.profiles.group,那么开启prod则就相当于激活了此组的全部环境。例如:
spring.profiles.group.prod=proddb,prodmq,prodmetrics
Importing扩展Configuration
现在,我们已经解决了配置文件处理的基本问题,我们终于能够考虑我们想要提供的新功能。我们使用SpringBoot2.4提供的主要功能是支持导入其他配置。
对于早期版本的SpringBoot,很难在application.properties和application.yml之外导入其他properties或yaml文件。可以使用spring.config.additional-location属性但它可以处理的文件类型非常有限。
在SpringBoot2.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可以被视为在声明它们的文档下方插入的其他文档。它们遵循与常规多文档文件相同的自上而下的顺序:导入仅被导入一次,无论声明了多少次。
volume挂载配置
导入定义使用与URL一样语法作为其值。如果您的位置没有前缀,则它被视为常规文件或文件夹。但是,如果您使用configtree:前缀,则告诉SpringBoot,您将期望在该位置使用Kubernetesvolume装载的配置树。
例如,您可以在application.properties配置:
spring.config.import=configtree:/etc/config
如果您有以下装载的内容:
etc/
+-config/
+-my/
| +-application
+-test
将在SpringEnvironment中拥有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。
版本回滚
正如上文所描述的,SpringBoot针对配置文件的功能变更是非常大的。考虑到低版本的兼容性
可以设置spring.config.use-legacy-processing=true属性即可,恢复到之前版本的文件处理机制。
如果发现关于此处的问题,则需要切换到旧版处理,请在GitHub上提出问题,官方将尝试解决该问题。
总结
官方希望新的配置数据处理更加好用,并且不会引起太多升级麻烦。如果您想了解更多有关它们的信息,可以查阅更新的参考文档。
到此这篇关于浅谈SpringBoot2.4配置文件加载机制大变化的文章就介绍到这了,更多相关SpringBoot2.4文件加载机制内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。