spring.profiles.include 跟 spring.profiles.active 的区别

spring.profiles.include 跟 spring.profiles.active 的区别

背景

我们经常看到springboot的 spring.profiles.active,有时也会看到 spring.profiles.include 这个配置,通常还是在spring.profiles.active 存在的情况下额外有include这个配置,那么区别是什么呢?

单用 spring.profiles.includespring.profiles.active 无区别,一起用的话,最终的profile的顺序是先include的,再active的,也就是active里的同名key会覆盖include的(后面的优先级更高),如

spring.profiles.active=A,B
spring.profiles.include=C,D

最终是这样的顺序 C,D,A,B

官方文档可以参考附录,其实官网虽然权威,但读起来干巴巴的,还是得结合自己动手做个实验加强对官网的描述的理解。

实验

  • application.properties

    spring.profiles.active=dev
    
  • application-dev.properties

    common.key=dev
    only.dev=dev
    
  • application-prod.properties

    common.key=prod
    only.prod=prod
    
  • java code

    @GetMapping("/getValue")
    public String getValue() {
          
          
      String[] activeProfiles = environment.getActiveProfiles();
      String[] defaultProfiles = environment.getDefaultProfiles();
      System.out.println("activeProfiles:" + Arrays.toString(activeProfiles));
      System.out.println("defaultProfiles:" + Arrays.toString(defaultProfiles));
      System.out.println("common.key:" + environment.getProperty("common.key"));
      System.out.println("only.dev:" + environment.getProperty("only.dev"));
      System.out.println("only.prod:" + environment.getProperty("only.prod"));
      return "success";
    }
    

打印结果

activeProfiles:[dev]
defaultProfiles:[default]
common.key:dev
only.dev:dev
only.prod:null

上述 application.properties 里的内容改成(不是加上!)

spring.profiles.include=dev

则打印

activeProfiles:[dev]
defaultProfiles:[default]
common.key:dev
only.dev:dev
only.prod:null

spring.profiles.active 一样的结果

如果 application.properties 的内容改成

spring.profiles.active=dev,prod

则打印

activeProfiles:[dev, prod]
defaultProfiles:[default]
common.key:prod
only.dev:dev
only.prod:prod

如果调换一下profile的顺序,改成

spring.profiles.active=prod,dev

则打印

activeProfiles:[prod, dev]
defaultProfiles:[default]
common.key:dev
only.dev:dev
only.prod:prod

可以发现 common.key 的值随着顺序的调整变了,后面的profile覆盖前面的

结论: spring.profiles.active=profile1,profile2 这种写法,相同key时后面的profile里的配置覆盖前面的(不相同的merge在一起)

spring.profiles.include=profile1,profile2也是后面的覆盖前面的?,测试一下:

# 如果 application.properties 的内容改成 spring.profiles.include=dev,prod 时所打印的结果如下
activeProfiles:[dev, prod]
defaultProfiles:[default]
common.key:prod
only.dev:dev
only.prod:prod

# 如果 application.properties 的内容改成 spring.profiles.include=prod,dev 时所打印的结果如下
activeProfiles:[prod, dev]
defaultProfiles:[default]
common.key:dev
only.dev:dev
only.prod:prod

可以发现 common.key 的值也是随着profile的顺序会受到影响

**结论:**spring.profiles.include 跟 spring.profiles.active 的配置一样,配多个profile的时候后面的profile里的key值t’h会覆盖前面的(如果key相同)

下面开始研究两种配置(active和include)同时存在的时候的行为,如果 application.properties 的内容改成

spring.profiles.active=dev
spring.profiles.include=prod

打印的日志

activeProfiles:[prod, dev]
defaultProfiles:[default]
common.key:dev
only.dev:dev
only.prod:prod

如果调换一下位置,application.properties 的内容改成

spring.profiles.active=prod
spring.profiles.include=dev

则测试结果是

activeProfiles:[dev, prod]
defaultProfiles:[default]
common.key:prod
only.dev:dev
only.prod:prod

结论:先将 include 里的profile排在前面,然后再排active的

如果active和include配置里头都有多个值的情况,即 application.properties 的内容改成如下

spring.profiles.active=dev,profileInActive
spring.profiles.include=prod,profileInInclude

则启动的时候打印的日志是(日志省略了不必要的信息)

The following profiles are active: prod,profileInInclude,dev,profileInActive

则可以进一步得到验证,最终profile的结果会是先把include的拿出来,然后再追加active的。另外profile不存在也不会报错,上述profileInInclude和profileInActive都是不存在的)

附录

上面是自己动手做实验,下面是官方的文档对于 spring.profiles.include 的解释

4.3.1. Adding Active Profiles
The spring.profiles.active property follows the same ordering rules as other properties: The highest PropertySource wins. This means that you can specify active profiles in application.properties and then replace them by using the command line switch.

Sometimes, it is useful to have profil-specific properties that add to the active profiles rather than replace them. The spring.profiles.include property can be used to unconditionally add active profiles. The SpringApplication entry point also has a Java API for setting additional profiles (that is, on top of those activated by the spring.profiles.active property). See the setAdditionalProfiles() method in SpringApplication.

For example, when an application with the following properties is run by using the switch, --spring.profiles.active=prod, the proddb and prodmq profiles are also activated:

---
my.property: fromyamlfile
---
spring.profiles: prod
spring.profiles.include:
  - proddb
  - prodmq

https://docs.spring.io/spring-boot/docs/2.2.1.RELEASE/reference/htmlsingle/ 搜 spring.profiles.include

读书笔记

  • 里面提到Sometimes, it is useful to have profil-specific properties that add to the active profiles rather than replace them, 其中有个错误的单词,应该是 profile-specific
    • 首先 xxx-specific的意思是,比如 “运动量的要求是个人体质-specific的”,意思是根据个人体质不同会有不同,简单说就是因人而异。所以xxx-specific就是根据xxx的不同会有不同
    • 这句话的意思,我理解就是有时候我们有些properties(其实就是key,比如上面的common.key),在include里的profile里的可以是增加进active里配置的profile的,而不是替换(意思应该就是include的profile是放在active的profile的前面的,所以不会替换掉active里的profile的key
  • The spring.profiles.include property can be used to unconditionally add active profiles,这句话的 unconditionally 比较难理解,评论区走起,它是什么意思?

猜你喜欢

转载自blog.csdn.net/w8y56f/article/details/129440205