56

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

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

例如,我有两个配置了环境配置文件的PropertySourcesPlaceholderConfigurerbean,"default"并对其进行了赋值。"dev"

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

dev配置文件会覆盖该配置文件吗default

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

4

4 回答 4

32

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

使用您的示例,如果-Dspring.profiles.active="default,dev"使用,配置文件中的propsbeandefault将在此处使用,仅仅是因为它是该 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.

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

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

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

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

于 2014-05-13T14:04:03.177 回答
17

最后一个定义获胜。我牢记在心,但是:

请务必记住,如果您在 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

所以请记住,最后的胜利,但资源就在外部之前

于 2020-06-05T19:30:50.197 回答
8

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

于 2017-06-05T15:00:16.590 回答
3

我不得不试验来说服自己。

从Spring Initializr创建最简单的 Spring Boot 应用程序

然后将 3 个属性文件添加到资源目录(第一个已经存在但为空)

# application.properties
foo=foo in application.properties
bar=bar in application.properties
baz=baz in application.properties

# application-foobar.properties
foo=foo in foobar override properties
bar=bar in foobar override properties

# application-barbaz.properties
bar=bar in barbaz override properties
baz=bar in barbaz override properties

然后我添加了这个@Config 类在启动时运行:

package com.example.profilesexperiment;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

@Configuration
class StartupConfig {

    @Autowired
    private Environment environment;

    @Value("${foo}")
    private String foo;

    @Value("${bar}")
    private String bar;

    @Value("${baz}")
    private String baz;

    @Bean
    CommandLineRunner startup() {
        return args -> {
            System.err.println("Active profiles: " + String.join(", ", environment.getActiveProfiles()));
            System.err.println("Foo = " + foo);
            System.err.println("Bar = " + bar);
            System.err.println("Baz = " + baz);
        };
    }
}

然后我用不同的配置文件组合运行它。您可以自己尝试,但这里有一些输出:

只是 foobar

java -Dspring.profiles.active=foobar -jar target/profiles-experiment-0.0.1-SNAPSHOT.jar   
Active profiles: foobar
Foo = foo in foobar override properties
Bar = bar in foobar override properties
Baz = baz in application.properties

foob​​ar 然后 barbaz

java -Dspring.profiles.active=foobar,barbaz -jar ...
Active profiles: foobar, barbaz
Foo = foo in foobar override properties
Bar = bar in barbaz override properties
Baz = bar in barbaz override properties

barbaz 然后 foobar

java -Dspring.profiles.active=barbaz,foobar -jar ...
Active profiles: barbaz, foobar
Foo = foo in foobar override properties
Bar = bar in foobar override properties
Baz = bar in barbaz override properties

判决:很明显,最后一个赢了!

哦,还有:非覆盖属性合并到一个大的快乐属性集(这就是来这里搜索的原因)

于 2022-01-18T19:53:28.623 回答