【问题标题】:Including profiles with spring.profiles.include seems to override instead of include使用 spring.profiles.include 包含配置文件似乎覆盖而不是包含
【发布时间】:2014-09-23 02:01:45
【问题描述】:

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

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

也许我只是在这里遗漏了一些东西。有没有更好的方法来做到这一点?谢谢。

【问题讨论】:

  • spring.profiles.include 的作用是影响Environment.getActiveProfiles() 所以你应该如何测试结果。您似乎正在使用两个配置文件中都存在的属性键进行测试(要应用的最后一个获胜,它可能是“bar”,因为它在 YAML 中最后出现)。
  • 感谢您的回复戴夫。这是我第一次听到这样解释。阅读 Spring Boot 参考文档,这当然不清楚(至少对我来说不是)。我认为这部分需要澄清,最好举个例子。谢谢。
  • 捐款总是被感激地接受。不过,我还不清楚要澄清什么。
  • 谢谢戴夫。我会尝试在我不那么丰富的业余时间里拼凑一些东西:-) 我想我的惊讶是我指定的包含实际上“隐藏”了指定包含的配置文件中的值。在我看来,我认为它有点像“子类”配置文件中的子类化和覆盖方法。我认为包含作为提供一些值的基类,并且包含它的“子类配置文件”将覆盖/隐藏“超类”配置文件提供的属性值。
  • 我犯了同样的错误,至少这是我的测试显示的。您的 YAML 不正确;指定两个“spring:profiles:” YAML 节点会导致第二个节点覆盖第一个节点。您最后一个 sn-p 中的“栏”实际上被忽略了。如果有某种方法可以使 YAML 节点既是标量又是集合,我不知道,并且很高兴欢迎更正。 docs.spring.io/spring-boot/docs/current/reference/htmlsingle/… 中的注释是一种糟糕的说法,即“spring.profiles.include”在特定于配置文件的 YAML 文档中不起作用。

标签: spring spring-boot


【解决方案1】:

尝试以下方法让 foo 包含但覆盖 bar,这似乎适用于我的解决方案

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

编辑:请注意,这是一个“黑客”,不受官方支持,适用于 2016 版

【讨论】:

  • 好@dpedro!我没有想过像那样明确地将几个配置文件设置为活动状态。这解决了我的问题。
  • @ArchimedesTrajano 这是可能的。请注意,Spring Boot 可能已经发生了变化,这个解决方案(真的是 hack)适用于 2 年前的版本
  • include 和 active 都支持多个值。 Last one 中存在的属性覆盖了先前存在的键。 spring.io 文档中通常缺少这些信息。
  • 从 Spring Boot 2.3.7.RELEASE 开始,这种“解决方法”似乎不再适用(至少,可能更早)。在我的情况下,我必须修改我的配置文件,以便我的默认值更通用(例如spring.datasource.url: jdbc:postgresql://${host}/{$database}),然后在配置文件中专门覆盖 - 即“正常”方式。我想一旦我们切换到>=2.4.0.RELEASE,可以使用配置文件组对分组进行更多清理。不幸的是,这显然不适用于所有情况,但如果您的基础设施全面干净,应该没问题。 YMMV。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-06
  • 2010-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-27
相关资源
最近更新 更多