使用spring.profiles.include包含配置文件似乎会覆盖而不是包含

使用spring.profiles.include包含配置文件似乎会覆盖而不是包含,spring,spring-boot,Spring,Spring Boot,我正在尝试对几个Spring引导应用程序的配置属性进行分区。我使用的是Spring Boot 1.1.6,我们的配置属性以通常的application.yml样式用YAML表示。我为公共基本参数、公共DB参数等创建了各种配置文件。我试图使用Spring Boot参考文档中提到的include功能,但它似乎是一种覆盖,而不是include。也就是说,与我想要的正好相反。鉴于application.yml中的以下内容,我希望属性name在bar配置文件处于活动状态时具有值bar,但它被设置为foo(

我正在尝试对几个Spring引导应用程序的配置属性进行分区。我使用的是Spring Boot 1.1.6,我们的配置属性以通常的application.yml样式用YAML表示。我为公共基本参数、公共DB参数等创建了各种配置文件。我试图使用Spring Boot参考文档中提到的include功能,但它似乎是一种覆盖,而不是include。也就是说,与我想要的正好相反。鉴于application.yml中的以下内容,我希望属性namebar配置文件处于活动状态时具有值bar,但它被设置为foo(来自包含的配置文件)。我认为include的概念意味着它首先被加载,并且在新概要文件中设置的任何同名属性都将覆盖来自include概要文件的属性。有点像,如果子类从超类隐藏字段,那么子类的任何实例都会反映隐藏的值。以下是文件:

spring:
  profiles: foo
name: foo

--- # New YAML doc starts here

spring:
  profiles: 
    include: foo
  profiles: bar
name: bar
如果我在显式激活“bar”配置文件的测试用例中运行此操作,则name属性仍将是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
但是,如果我将其注释掉,则包括:

spring: 
profiles: bar
#  profiles: 
#    include: foo
并在我的代码中显式激活两个配置文件:

builder.profiles("foo", "bar");
然后它会像我预期的那样工作,name属性被设置为bar。我宁愿处理YAML文件中的包含的主要原因是它对我的实际代码影响较小,并且我可以在一个地方管理所有概要文件包含。使用另一种方法,如果要重命名配置文件,我必须在整个项目中搜索配置文件字符串和可能的@profile注释。这肯定更容易出错。我认为一个更灵活的解决方案是能够明确表示包含的概要文件是否覆盖子概要文件值。可能是这样的:

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

也许我只是错过了一些东西。有更好的方法吗?谢谢

foo尝试以下操作,以包括但覆盖,似乎对我的解决方案有效

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

编辑:请记住,这是一个“黑客”,不是官方支持的,它是2016版的

spring.profiles.include的功能是影响
环境。getActiveProfiles()
,所以你应该这样测试结果。您似乎正在使用两个配置文件中都存在的属性密钥进行测试(最后一个应用的属性密钥是wins,它可能是“bar”,因为它在YAML中是最后一个)。感谢您的回复Dave。这是我第一次听到这样的解释。阅读SpringBoot参考文档,这当然不清楚(至少我不清楚)。我认为这一部分需要澄清,最好是举个例子。谢谢。捐款总是被感激地接受。我还不清楚澄清的内容。谢谢戴夫。我将尝试在我不那么丰富的业余时间里做一些事情:-)我想我感到惊讶的是,我指定的include实际上“隐藏”了指定include的概要文件中的值。在我看来,这有点像“子类”概要文件中的子类化和重写方法。我认为include是提供一些值的基类,而包含它的“子类概要文件”将覆盖/隐藏“超类”概要文件提供的属性值。我犯了同样的错误,至少我的测试显示了这一点。您的YAML不正确;指定两个“spring:profiles:”YAML节点会导致第二个节点覆盖第一个节点。最后一个代码片段中的“条”实际上被忽略了。如果有某种方法可以使YAML节点同时成为标量和集合,我不知道这一点,并且很乐意接受更正。中的注释是一种糟糕的说法,表示“spring.profiles.include”在特定于概要文件的YAML文档中不起作用。Nice@dpedro!我没有想到要明确地将几个配置文件设置为那样的活动状态。“这就解决了我的问题。”阿基米德拉贾诺说,“这是可能的。”。请注意,Spring Boot中可能有一些更改,此解决方案(hack,真的)适用于2年前的版本,Include和active都支持多个值。上一个中存在的属性将替代上一个中存在的键。通常,spring.io文档中缺少此类信息。