Spring-Boot application.yml 文件拆分,实现 maven 多环境动态启用 Profiles

在实际使用环境中,我们同一个应用环境可能需要在不同环境运行(开发、测试、生产等),每个环境的参数都有可能不同(连接参数、日志级别等),使用 Spring-Boot 的 Profiles 可以将不同环境下的参数进行拆分,并指定加载。

1. 使用 Spring-Boot Profiles 拆分 application.yml 文件

首先我们有一个非常简单的 application.yml 文件

database: mysql
spring:
    datasource:
        url : jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8
        username : root
        password : 12345678

我们现在有开发环境(dev)、测试环境(test)、生产环境(prod)

修改application.yml 文件

database: mysql

spring:
  profiles:
    active: dev

#这两行实际没意义,如果有其他公共参数可以补充进来
spring:
    datasource:

#开发环境
spring:
  profiles: dev

spring:
    datasource:
        url : jdbc:mysql://127.0.0.1:3306/dev?characterEncoding=UTF-8
        username : root
        password : 12345678

#测试环境
spring:
  profiles: test

spring:
    datasource:
        url : jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8
        username : root
        password : 12345678

#生产环境
spring:
  profiles: prod

spring:
    datasource:
        url : jdbc:mysql://127.0.0.1:3306/prod?characterEncoding=UTF-8
        username : root
        password : 12345678

我们只需要在 spring.profiles.active 指定使用的 profiles

当然目前来说,这种配置文件并不符合我们的需求,我们需要把不同环境的参数放到不同的文件中。

通过与配置文件相同的命名规范,创建 application-{profiles}.yml 文件 存放不同环境的参数。

修改 application.yml

database: mysql

spring:
  profiles:
    active: dev

#这两行实际没意义,如果有其他公共参数可以补充进来
spring:
    datasource:

创建 application-dev.yml

spring:
    datasource:
        url : jdbc:mysql://127.0.0.1:3306/dev?characterEncoding=UTF-8
        username : root
        password : 12345678

2. 启动参数

如果 spring.profiles.active 没有指定值,那么只会使用没有指定 spring.profiles 的值,也就是只会加载通用的配置。

并且我们可以在启动应用程序的时候,对 spring.profiles.active 进行指定,这样就不需要每次修改环境都需要手动修改配置文件再编译。

例如运行 Jar 包,指定使用 dev 环境参数:

java -jar xxx.jar --spring.profiles.active=dev

3. 使用 Maven 在打包时只加载特定的 Profiles 配置文件

由于各种各样的原因,我们肯定希望打出哪个环境的包,就只需要包含这个环境的配置文件即可,不想包含其他环境的配置文件,这时候可以直接在 maven 中使用 profilesresources 来配置,打包时使用 mvn package -P dev 即可,仍然使用 java -jar xxx.jar --spring.profiles.active=dev 来运行。

<profiles>
    <!--开发环境-->
    <profile>
        <id>dev</id>
        <properties>
            <spring.profiles.active>dev</spring.profiles.active>
        </properties>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <!--测试环境-->
    <profile>
        <id>test</id>
        <properties>
            <spring.profiles.active>test</spring.profiles.active>
        </properties>
    </profile>
    <!--生产环境-->
    <profile>
        <id>prod</id>
        <properties>
            <spring.profiles.active>prod</spring.profiles.active>
        </properties>
    </profile>
</profiles>
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/resources.${spring.profiles.active}</directory>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

4. 使用 Maven 在打包时自动通知 Spring-Boot 加载的 Profiles 环境参数

虽然每次都可以打包成相应配置文件的 Jar 包,但是每次运行,都得用 --spring.profiles.active 参数来指定运行环境,打包时指定一次,运行时指定一次,确实很麻烦。

不自动不舒服,下面我们就来看看怎么把这个参数可以省略掉。

首先我们得知道,加这个参数的原因就是想着项目中存在多个环境,这个环境是需要在 application.yml 中配置,或者运行时通过参数指定。

实际上我们在使用 maven 打包时就能确定我们所选的运行环境,所需要的配置文件,那么我们不想在运行时通过参数来指定,那么我们可不可以修改 application.yml 配置文件呢,这样就不需要我们运行时来指定参数了吧。

下面就介绍两种方法来实现这个功能:

4.1. 方法1:利用 maven filter 来替换标记的内容

这个方法直接在上一步的基础上,增加一个占位符标记,并且在 resource 中将过滤器打开。

修改 pom.xml 文件

<!-- profiles部分不变 -->
<properties>
    <resource.delimiter>#</resource.delimiter>
</properties>
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/resources.${spring.profiles.active}</directory>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

修改 application.yml 文件

spring:
    profiles:
        active: #spring.profiles.active#

这里我们通过 <resource.delimiter>#</resource.delimiter> 重写定义了一个占位符,其实熟悉 maven 的朋友都知道,maven 本身有自带的占位符 ${...} ,但是在 Spring-Boot 中不行,这个占位符被 Spring-Boot 占用了,所以我们就得重新定义一遍。再通过 <filtering>true</filtering> 这样的一个设置,打开过滤器开关,这样 application.yml 文件中的 #spring.profiles.active# 部分就会替换为 pom.xmlprofiles 中定义的 spring.profiles.active 变量值。

4.2. 方法2:利用 maven-resources-plugin 插件

maven 的 maven-resources-plugin 插件使用方法也是很简单的,首先,干掉我们上面所用的 <build><resources></resources></build> 这插件就是用来代替他的高级版。

接着我这里有一个示例,一看就懂的那种。

修改 pom.xml 文件

&lt;!-- profiles部分不变 --&gt;
&lt;build&gt;
    &lt;plugins&gt;
		&lt;plugin&gt;
            &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
            &lt;artifactId&gt;maven-resources-plugin&lt;/artifactId&gt;
            &lt;version&gt;2.7&lt;/version&gt;
            &lt;executions&gt;
                &lt;execution&gt;
                    &lt;id&gt;default-resources&lt;/id&gt;
                    &lt;phase&gt;validate&lt;/phase&gt;
                    &lt;goals&gt;
                        &lt;goal&gt;copy-resources&lt;/goal&gt;
                    &lt;/goals&gt;
                    &lt;configuration&gt;
                        &lt;outputDirectory&gt;target/classes&lt;/outputDirectory&gt;
                        &lt;useDefaultDelimiters&gt;false&lt;/useDefaultDelimiters&gt;
                        &lt;delimiters&gt;
                            &lt;delimiter&gt;#&lt;/delimiter&gt;
                        &lt;/delimiters&gt;
                        &lt;resources&gt;
                            &lt;resource&gt;
                                &lt;directory&gt;src/main/resources/&lt;/directory&gt;
                                &lt;filtering&gt;true&lt;/filtering&gt;
                            &lt;/resource&gt;
                            &lt;resource&gt;
                                &lt;directory&gt;src/main/resources.${spring.profiles.active}&lt;/directory&gt;
                                &lt;filtering&gt;false&lt;/filtering&gt;
                            &lt;/resource&gt;
                        &lt;/resources&gt;
                    &lt;/configuration&gt;
                &lt;/execution&gt;
            &lt;/executions&gt;
        &lt;/plugin&gt;
    &lt;/plugins&gt;
&lt;/build&gt;

修改 application.yml 文件

spring:
    profiles:
        active: #spring.profiles.active#

注意看 pom.xml 中的 <delimiter>#</delimiter> 定义了一个占位符,可以在复制文件的时候,在文件中查找 #...# 将其中的内容进行替换。

通过以上两种方法修改后,再次运行 mvn package -P dev 打包,将生成的 Jar 包用 RAR 解压,直接查看 application.yml 文件,我们可以看到原来的 #spring.profiles.active# 已经被替换成了 dev ,这样在运行 Jar 包时就不需要进行参数指定,直接运行 java -jar xxx.jar 即可。


参考链接

Spring Boot教程 – Spring Boot Profiles实现多环境配置切换

如何在@SpringBootTest中动态地启用不同的profiles

spring boot通过maven filter替换properties属性(多环境配置)

5 条评论

发表回复

*