Spring“spring.profiles.include”覆盖

时间:2017-11-18 16:03:42

标签: spring spring-boot spring-profiles

我的目的是在spring boot应用程序中有两个配置文件 - 开发和生产。开发配置文件仅用于覆盖生产配置文件的某些变量(如内存数据库而不是云中的数据库)。由于我预计将来会对生产配置文件进行一些更改,因此在开发配置文件中复制变量似乎不是一种解决方案。

所以,在Spring Reference中,我读到spring.profiles.include应该只添加引用的配置文件中的属性,但是从我检查它的内容中覆盖了它。因此,当有两个配置文件foo和bar时,在单独的yaml文件中:

应用foo.yaml:

myproperty: 44

应用bar.yaml:

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

在IDE中设置-Dspring.profiles.active=bar变量,myproperty的运行时值为44.这意味着barfoo覆盖,spring.profiles.active=bar应该只添加属性,但不要覆盖它们。启动应用程序时,我得到:

  

以下个人资料有效:foo,bar

我按照answer的建议将application-bar.yaml添加到{{1}},在另一个问题中,但它没有效果 - 当属性存在与否时没有区别(我也试过了)使用破折号列表而不是逗号分隔值。)

我的问题是,它应该如何工作(那么Spring Reference会产生误导)?如果是的话,有没有解决方案?

在github上的应用程序源代码中添加link

6 个答案:

答案 0 :(得分:6)

我们以稍微不同的方式实现了Spring活动配置文件。我们假设默认属性文件application.yml包含生产和开发环境中相同的所有默认值。

分别为名为application-prd.ymlapplication-dev.yml的生产和开发文件创建单独的属性。这些文件可能包含其他属性或覆盖某些默认属性。

在应用程序启动期间,我们将spring.profiles.active作为环境变量传递。例如,

-Dspring.profiles.active=prd

将随application-prd.yml

一起提取application.yml

-Dspring.profiles.active=dev

将随application-dev.yml

一起提取application.yml

答案 1 :(得分:4)

根据spring boot文档herespring.profiles.include用于添加其他配置文件中的属性。如果该属性不存在于活动属性中,它将从其他配置文件添加该属性。但是如果它存在,那么它将覆盖并且最后一个要应用

答案 2 :(得分:2)

Spring Boot 2.4 更改了包含多个配置文件的机制,以使用新的 profile groups 功能,而不是在特定于配置文件的文档中使用 return。这意味着您的配置对于新版本的 Spring Boot 不再有效,需要更改。

也就是说,您的用例似乎不太适合配置文件组,因为它并没有真正结合两个配置文件,而是覆盖默认值。因此,我建议使用建议的 in another answer 方法,将通用和默认属性放在共享的 converter.php 文件中,并且仅在配置文件特定的文档中包含特定于环境的值和覆盖。

application.yaml

spring.profiles.include

application-bar.yaml

application.yaml

请注意,Spring Boot 支持 multi-document files,因此如果需要,可以将它们组合成一个 spring: myproperty: 44 # Default value 文件:

spring:
  myproperty: 55 # Override default

相关 2.4 变更

从 Spring Boot 2.4 开始,在特定于配置文件的文档中不再可能使用 application.yaml,除非使用 spring: myproperty: 44 # Default value --- spring.config.activate.on-profile=bar # These configs apply to the bar profile spring: myproperty: 55 # Override default 启用 legacy mode。根据 2.4 Spring Boot Config Data Migration Guide:

<块引用>

您仍然可以使用 spring.profiles.include 属性,但只能在非特定于配置文件的文档中使用。

此方法已被 profile groups 功能取代。根据{{​​3}}:

<块引用>

如上所述,在特定于个人资料的文档中无法再使用 spring.profiles.include,因此该文件无效。

由于此用例非常普遍,因此我们尝试提供另一种方法来支持它。在 Spring Boot 2.4 中,您可以使用 migration guide 功能。

Spring Boot 参考指南的 “profile groups” 部分记录了此功能:

<块引用>

配置文件组允许您为相关的配置文件组定义逻辑名称。

例如,我们可以创建一个 spring.config.use-legacy-processing=true 组,其中包含我们的 spring.profiles.includeproduction 个人资料。

proddb

我们的应用程序现在可以使用 prodmq 启动,一键激活 spring: profiles: group: production: - "proddb" - "prodmq" --spring.profiles.active=productionproduction 配置文件。

迁移指南 Profile Groups proddb 属性不能用于特定于配置文件的文档。

<块引用>

不能在特定于配置文件的文档中使用 prodmq 属性。

答案 3 :(得分:1)

您可以在application-bar.yaml中添加新的个人资料:

spring.profiles.include: foo,foo-override
myproperty: 33

---
spring.profiles: foo-override
myproperty: 55

顺序为:33 in bar44 in foo覆盖,而55 in foo-override覆盖。

答案 4 :(得分:0)

这里的问题分为两部分:

第一个出现在原始问题(here)中提到的答案中。即如何从配置文件继承属性。 答案是包括原始配置文件。但是对于这种情况,可能不需要。

第二个问题是激活配置文件的方式有所不同。我相信(但可能会发现错误),在提到的问题中,OP不会通过以下方式激活配置文件:

-Dspring.profiles.active=bar

此行将覆盖配置文件中提供的所有内容。因此,对于这种情况,继承属性的最简单解决方案是将IDE中的行更改为:

-Dspring.profiles.active=bar,foo

然后,您可以忽略foo中存在于bar中的属性,也可以忽略spring.profiles.include,但是在这种情况下,foo将不是独立的配置文件。如果可以的话-可以这样工作。

答案 5 :(得分:0)

给出:

  • 文件:application-default.yml, application-foo.yml, application-bar.yml
  • myproperty: default在application-default.yml中
  • myproperty: foo在application-foo.yml中
  • myproperty: bar在application-bar.yml中

我认为这两种使用配置文件的用例在含义上有些相反:

  1. 在最常见的情况下(-Dspring.profiles.active,但没有spring.profiles.include):

    1. 激活配置文件foo或boo时,来自 application-foo.yml(或application-bar.yml)将添加/覆盖 来自application-default.yml。
    2. 激活配置文件foo,bar时,bar的属性将添加/覆盖application-foo.yml中的属性,然后是application-default.yml中的属性。

    例如:-Dspring.profiles.active=foo,bar来自application-bar.yml的属性获胜(覆盖)-> myproperty: bar

  2. 在第二种情况下(使用spring.profiles.include

    1. include语句中的属性添加/覆盖使用spring.profiles.include的application-*。yml文件中的属性

    即:如果application-boo.yml包含spring.profiles.include=foo,则application-foo.bar adds/override properties from from application-bar.yml中的属性会添加/覆盖application-default.yml中的属性。

    另一方面(我想),如果application-boo.yml包含spring.profiles.include=default,foo,则application-foo.yml的属性将添加/覆盖application-default.yml的属性,而这些属性会添加/覆盖{ {1}}。 application-bar.yml这样。我不建议将myproperty: bardefault结合使用,因为这种方式将两种情况混合使用,并且考虑到spring.profiles.include在springboot中有特殊处理,因此覆盖策略是违反直觉的。

我也承认我完全不喜欢application-*。yml文件中的application-default.yml用法。我更喜欢使用系统属性(包括Maven)或env变量来激活配置文件。 IMO,这使整个配置文件对我来说更清楚。

如果出于上述原因,我走错了路,请告诉我。