【问题标题】:What is the order of precedence when there are multiple Spring's environment profiles as set by spring.profiles.active当 spring.profiles.active 设置多个 Spring 的环境配置文件时,优先顺序是什么
【发布时间】:2014-06-30 08:02:26
【问题描述】:

我只是想知道当指定多个 Spring 活动配置文件时,优先顺序是什么

假设我希望 default 配置文件处于活动状态,但当有多个相同的元素(例如 bean)可供选择但配置文件不同时,dev 配置文件会覆盖它...

例如,我有两个 PropertySourcesPlaceholderConfigurer bean 配置了 "default""dev" 值环境配置文件。

如果我使用以下配置文件激活:-Dspring.profiles.active="default,dev"

dev 配置文件会覆盖 default 吗?

如果不是,如何实现上述行为?

【问题讨论】:

  • AFAIK,配置文件之间定义的唯一“优先级”是基于 bean 的声明顺序(就像覆盖任何 bean 的定义一样),最后一个特定于配置文件的 bean 获胜。因此,如果您在两个配置文件中都有一个带有 id="dataSource" 的 bean,那么将使用该 bean 的最后一个定义,因为第一个定义将被最后一个定义覆盖。 spring.profiles.active 中配置文件的顺序实际上并不重要。

标签: spring spring-profiles


【解决方案1】:

spring.profiles.active 系统属性中配置文件的顺序无关紧要。 “优先级”由 bean 的声明顺序定义,包括特定于配置文件的 bean,最后一个 bean 定义获胜

使用您的示例,如果使用 -Dspring.profiles.active="default,dev",则此处将使用 default 配置文件中的 props bean,因为它是该 bean 的最后一个活动定义:

<beans profile="dev">
    <bean id="props" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
        <property name="location" value="classpath:META-INF/dev.properties"/>
    </bean>
</beans>
<beans profile="default">
    <bean id="props" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
        <property name="location" value="classpath:META-INF/default.properties"/>
    </bean>
</beans>

反转 bean 的顺序,然后将使用 dev 版本,无论配置文件在 spring.profiles.active 中如何排序。

请注意,我没有使用 &lt;context:property-placeholder/&gt;,因为它不允许您显式指定 bean id,因此我不确定如果使用多个 bean 会表现出什么行为。我想这些属性将被合并,因此两者定义的属性将使用最后一个定义,但每个文件的特定属性将保持不变。

否则,根据我的经验,您通常会按以下顺序定义 bean:

  1. “默认”bean 定义,不特定于配置文件
  2. 在特定于环境的配置文件中覆盖 bean 定义
  3. 覆盖测试特定配置文件中的 bean 定义

这样,如果与其他配置文件结合使用,测试配置文件 bean 会胜出;否则,您将使用特定于环境的 bean 或基于配置文件的默认 bean。

【讨论】:

  • 它如何与类路径扫描一起工作?我想这不是确定性的,但如果这个或另一个答案能更新这个,那就太好了。
  • @musiKk 好问题。使用 XML 文件,我们可以在同一个文件中定义多个具有相同 id 的 bean,从默认值开始,然后用特定于配置文件的 bean def 覆盖它。使用类路径扫描,您可能希望使用定义相同 bean 的不同类(文件)并使用 @Profile 注释来选择激活 bean 的配置文件。在这种情况下,使用默认 bean 可能意味着指定一个“默认”配置文件(例如@Profile("default"))或指定哪些配置文件应该不存在(例如@Profile("!dev"))。
  • @superEb springBoot documentation 表示顺序很重要
  • @Prakash 我也对排序有疑问,我有两个不同的配置文件,比如 stage 和 stage-qa,如果在两个文件中都定义了属性(键),那么我定义 spring 活动配置文件的方式很重要。如果 -Dspring.active.profiles=stage,stage-qa 则 stage-qa 优先,如果我将其反转,则按顺序进行。你能帮我理解这种行为吗?
  • 2.3.3 Profile Specific Files 章节中写道:“如果指定了多个配置文件,则应用最后获胜的策略。”
【解决方案2】:

最后一个定义获胜。我记住了,但是:

请务必记住,如果您在 jar 资源中有一些 application.properties 的默认内容,那么此资源内容将覆盖不太重要的配置文件的外部内容(之前在spring.profiles.active 中定义的其他配置文件)的条目。

示例配置文件:spring.profiles.active=p1,p2,p3

Jar 资源中的文件application-p1.propertiesapplication-p3.properties

外部文件:application-p1.propertiesapplication-p2.properties

最终顺序将是(最后获胜):

  1. 资源 application.properties
  2. 外部application.properties
  3. 资源 application-p1.properties
  4. 外部application-p1.properties
  5. 外部application-p2.properties
  6. 资源 application-p3.properties - 这就是诀窍!这将使用 p3 的资源版本中的值覆盖在 p1 和 p2 的外部文件中定义的属性
  7. 外部application-p3.properties

所以请记住,最后的胜利,而且资源就在外部

之前

【讨论】:

  • 这写在某些文档中吗?我前段时间问过类似的问题 - stackoverflow.com/questions/60333056/… 但没有答案(最近关闭了)。我知道,当我提供p1,p2 时,它是在订单之后的那一刻,我可以依赖它吗?
  • 2.3.3 Profile Specific Files 章节中写道:“如果指定了多个配置文件,则应用最后获胜的策略。”
  • 我已经检查过了。 Last-wins 已记录在案。我的帖子与获胜配置文件(最后一个)覆盖其他配置文件外部设置的设置但具有获胜配置文件资源内容的情况有关。顺便说一句,Betlista 感谢您提供参考链接。
【解决方案3】:

superEB 是对的,配置文件的顺序对 bean 来说并不重要,声明顺序在那里更重要,但请记住,如果您使用基于配置文件的配置文件,顺序很重要!

【讨论】:

  • 这是否意味着如果我使用这里描述的方法 stackoverflow.com/a/48809611/2458858 ,并且我想选择多个配置,我将无法选择?因为最后一个会覆盖以前的?或者它们会因为有单独的配置类而工作吗? (假设我将每个配置标记为单独的配置文件)
  • 如果一个使用基于配置文件的配置并且多个每个配置文件的配置文件定义相同的属性。优先顺序是什么?
  • 据我所知顺序没有定义,但是为了这个最好问一个专门的Stack溢出问题,这样如果没有其他人有好的答案,spring团队也可以回答
  • 2.3.3 Profile Specific Files 章节中写道:“如果指定了多个配置文件,则应用最后获胜的策略。”
猜你喜欢
  • 2018-06-12
  • 1970-01-01
  • 2022-08-12
  • 1970-01-01
  • 1970-01-01
  • 2015-07-25
  • 2015-07-25
  • 2010-12-12
  • 1970-01-01
相关资源
最近更新 更多