# spring.profiles.active 和 spring.profiles.include 的使用 / 区别

# 业务场景

一套程序可能会被部署到不同的环境,开发,测试,生产环境有不同的配置信息,包括 jdbc 地址,ip,端口等。如果在同一个配置文件中,每次部署去改配置,会非常麻烦且容易出错

# 优化方式

spring.profiles.active 属性

一个好方法就是创建不同的配置文件,且命名规则遵循 application-${profile}.properties,例如:

  1. 开发环境配置文件:application-dev.properties
  2. 测试环境配置文件:application-test.properties
  3. 生产环境配置文件:application-prod.properties

当然,我们不能删除项目最顶层的 application.properties 配置,在该文件中,根据部署场景不同,切换不同的配置文件:配置 spring.profiles.active,属性值为 $

  1. spring.profiles.active=dev:启用 application-dev.properties
  2. spring.profiles.active=test:启用 application-test.properties
  3. spring.profiles.active=prod:启用 application-prod.properties

在此推荐一个结合 pom.xml 的配置方式:

application.properties 中配置:

spring.profiles.active=@sys.pro.type.active@

pom.xml 配置:

<profiles>
	<profile>
      	   <!--id 唯一性比如:test 或 dev-->
            <id>xxx</id>
            <properties>
                <!-- 标签命名可以随意但是有意义比如环境就是 dev-->
                <sys.pro.env>${profileActive}</sys.pro.env>
                <sys.pro.type>datasience</sys.pro.type>
                <sys.pro.type.active>${profileActive}</sys.pro.type.active>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
    </profile>
</profiles>

# 启动时指定

在执行有参启动时,可以再命名中进行指定要选用的配置文件,例如:

java -jar xx.jar --spring.profiles.active=test

这个命名优先级是最高的,即使 application.properties 中已经配置 spring.profiles.active=dev,最终程序还是会用 application-test.properteis 配置文件。

# spring.profiles.include 属性

再进一步,对于开发环境,想 用不同的配置文件存储开发环境不同的配置 ,例如:

application-dev1.properties 中存储 jdbc 信息

application-dev2.properties 中存储 ip,端口信息

即在启用 application-dev.properties 开发环境 (主) 配置文件时,同时启用 application-dev1.properties 和 application-dev2.properties。那么,可以使用 spring.profiles.include 属性:同时启用其它的 profile

# 配置方法

  1. 若是 properties 文件:spring.profiles.include=dev1,dev2

  2. 若是 yaml 文件中

    spring.profiles.include:
    -dev1
    -dev2
    或者:spring.profiles.include:dev1,dev2

# 配置的位置和区别:

  1. 配置方式一:application.properies 中,配置 spring.profiles.active=dev 的同时指定 spring.profiles.include=dev1,dev2
  2. 配置方式二:application.properties 中,配置 spring.profiles.active=dev,application-dev.properties 中,配置 spring.profiles.indclude=dev1,dev2。使用 application-dev.properties 时自定就激活了 dev1,dev2 两个文件,不用再次指定。(个人认为第二种方法更好)

# 区别:

  1. 第一种方式启动时,控制台打印 The following profiles are active:dev1,dev2,dev

  2. 第二种方式启动时,控制台打印 The following profiles are active:dev, dev1,dev2

    按照顺序, 后面的覆盖前面的

# 用示例来使用和区分

在某个工程里,我依据开发,生产环境,以及它们要同时激活的配置,创建了多个配置,分别如下:

application-dev.properties 配置:

my.name=dev
my.height=170
#同时触发 dev1 和 dev2 的激活
spring.profiles.include=dev1,dev2

application-dev1.properties 配置:

my.name=dev1
my.height=171

application-dev2.properteis 配置:

my.name=dev2
#my.height=172

application-prod.properties 配置:

my.name=prod
my.height=180

application-prod1.properties 配置:

my.name=prod1
my.height=181

application-prod2.properties 配置:

my.name=prod2
my.height=182

# 测试一:

在 application.properties 配置文件中,指定

#激活的是开发环境配置文件
spring.profiles.active=dev

启动时不指定参数

结果:打印的内容为:姓名:dev2,身高:171

原因:

  1. 先加载 application.properties

  2. 再加载 application-dev.properties

    my.name=dev

    my.height=170

  3. 加载 application-dev1.properties

    my.name=dev1

    my.height=171

  4. 加载 application-dev2.properties

    my.name=dev2

    my.height=171

# 测试二:

在 application.properties 配置文件中,指定

#激活的是生产环境配置文件
spring.profiles.active=prod
#同时触发 prod1 和 prod2 的激活
spring.profiles.include=prod1

启动时不指定参数

结果:

The following profiles are active: prod1,prod2,prod

打印内容为:姓名:prod,身高:180

# 测试四:

在 application.properties 配置文件中,指定 my.height=185,且把 dev、dev1、dev2 里 my.height 配置都删掉,最终结果是:身高:185。(application.properties 会作那个最保底的配置文件)。
如果把 application.properties 里的 my.height 配置也删掉,那请求就得报错啦。