当有多个由spring.profiles.active设置的Spring环境配置文件时,优先级顺序是什么



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

说我希望default配置文件是活动的,但dev配置文件覆盖它,当有几个相同的元素(例如bean)选择,但有不同的配置文件…

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

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

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

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

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中的概要文件如何排序。

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

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

  1. "默认"bean定义,而不是特定于配置文件
  2. 在特定于环境的配置文件中重写bean定义
  3. 在特定于测试的配置文件中重写bean定义

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

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

这是非常重要的要记住,如果你有一些默认的应用程序内容。属性,那么这个资源内容将覆盖来自不太重要的概要文件(spring.profiles.active中前面定义的其他概要文件)的外部内容的条目。

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

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

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

最终订单将是(最后获胜):

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

所以请记住最后获得而且资源正好在外部

之前

我不得不试着说服自己。

从spring Initializr创建最简单的spring引导应用程序

然后添加了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

foobar then 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 then 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

结论:显然,最后一个赢!

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

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

相关内容

  • 没有找到相关文章

最新更新