使用spring.profiles.include包含配置文件似乎会覆盖而不是包含 [英] Including profiles with spring.profiles.include seems to override instead of include

查看:1547
本文介绍了使用spring.profiles.include包含配置文件似乎会覆盖而不是包含的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对几个Spring Boot应用程序的配置属性进行分区.我使用的是Spring Boot 1.1.6,我们的配置属性以YAML的常规application.yml样式表示.我已经为常用的基本参数,常用的数据库参数等创建了各种配置文件.我试图使用Spring Boot参考文档中提到的include功能,但它似乎是一个替代而不是include. IE.与我想要的完全相反.给定application.yml中的以下内容,当 bar 配置文件处于活动状态时,我希望属性 name 的值为 bar .而是将其设置为 foo (从随附的配置文件中).我认为include的概念意味着它首先被加载,并且在新配置文件中设置的任何名称相同的属性都将覆盖包含的配置文件中的那些属性.有点像子类正在遮罩超类中的字段,子类的任何实例都会反映出遮蔽的值.这是文件:

I'm trying to partition configuration properties for several Spring Boot applications. I'm using Spring Boot 1.1.6, and our configuration properties are expressed in YAML in the usual application.yml style. I've created various profiles for common base parameters, common DB parameters, etc. I was trying to use the include feature mentioned in the Spring Boot reference docs, but it seems to work as an override and not an include. I.e. exactly the opposite of what I want. Given the following content in application.yml, I would have expected the property name to have the value bar when the bar profile is active, but instead it gets set to foo (from the included profile). I thought the notion of including meant that it was loaded first, and any identically named properties set in the new profile would override those from the included profile. Kind of like if a subclass is shadowing a field from the superclass, any instance of the subclass would reflect the shadowed value. Here's the file:

spring:
  profiles: foo
name: foo

--- # New YAML doc starts here

spring:
  profiles: 
    include: foo
  profiles: bar
name: bar

如果我在显式激活"bar"配置文件的测试用例中运行此命令,则 name 属性仍为foo:

If I run this in a test case with the "bar" profile explicitly activated, the name property will still be foo:

SpringApplicationBuilder builder = new SpringApplicationBuilder(Application.class);
SpringApplication app = builder.application();
builder.profiles("bar");
ConfigurableApplicationContext ctxt = app.run();
String name = ctxt.getEnvironment().getProperty("name"); // Is always "foo" much to my surprise

但是,如果我注释掉包括:

However, if I comment out the include:

spring: 
profiles: bar
#  profiles: 
#    include: foo

并在我的代码中显式激活两个配置文件:

and activate the two profiles explicitly in my code:

builder.profiles("foo", "bar");

然后按预期运行,并且 name 属性设置为 bar .我宁愿处理YAML文件中的包含的主要原因是,它对我的​​实际代码的影响较小,并且我可以在一个地方管理所有配置文件包含.使用另一种方法,如果要重命名配置文件,则必须在整个项目中搜索配置文件字符串和可能的@Profile注释.绝对更容易出错.我认为更灵活的解决方案是显式地表达所包含的配置文件是否覆盖子配置文件的值.也许像这样:

Then it works as I would expect, and the name property is set to bar. The main reason I would rather handle the includes in the YAML files is that it's less impact on my actual code, and I can manage all profile inclusion in one place. With the other approach, I'd have to search for profile strings and possible @Profile annotations in my entire project if I were to ever rename the profiles. That's definitely more error prone. I think a more flexible solution would be to explicitly be able to express whether or not the included profile overrides the sub profile values or not. Maybe something like:

spring:
  profiles: bar
  profiles:
    include: foo
      override: false

也许我只是在这里想念一些东西.有更好的方法吗?谢谢.

Maybe I'm just missing something here. Is there a better way of doing this? Thanks.

推荐答案

尝试以下操作使 foo 包含但覆盖 bar ,似乎适用于我的解决方案

Try the following for foo to include but override bar, seems to be working for my solution

spring:
    profiles:
        include: bar
        active: foo,bar

请注意,这是一个"hack",未得到官方支持,适用于2016版

edit: please mind, that it's a "hack", not officially supported and it's for 2016 version

这篇关于使用spring.profiles.include包含配置文件似乎会覆盖而不是包含的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆