Spring Boot 项目通过 Maven profiles 使用 -P 支持项目多环境配置打包

Posted carl-zhao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot 项目通过 Maven profiles 使用 -P 支持项目多环境配置打包相关的知识,希望对你有一定的参考价值。

在我们进行项目开发的时候,都会把一些固定的值添加到配置文件当中进行集中管理。如果更近一步就是通过配置中心进行管理,但是配置中心的地址也是需要配置在项目中的配置文件当中的。一般在项目当中分为不同的环境,比如:

  • local 环境:本地环境,一般是开发人员在本地进行开发测试的环境
  • dev 环境:开发环境,外部用户无法访问,开发人员使用,版本变动很大。
  • test 环境:测试环境,外部用户无法访问,专门给测试人员使用的,版本相对稳定。
  • uat 环境:User Acceptance Test 用户验收测试,一般用于商户对接使用
  • pre 环境:灰度环境,外部用户可以访问,但是服务器配置相对低,其它和生产一样。
  • pro环境:生产环境,面向外部用户的环境,连接上互联网即可访问的正式环境。

多个环境当中代码逻辑肯定是一样的,不同的是他们的配置文件中的配置参数肯定是不一样的。比如:数据库连接信息, Redis 连接信息,远程调用第三方 http 地址或者其它各种中间件的访问地址都是不一样的。

一般我们项目是使用 maven 来进行项目管理的,当然 gradle 也可以作为项目管理。它应该也具有类似的功能,今天我们就讨论 maven 的使用,如何对 gradle 感兴趣的朋友可以自行了解。

1、什么是 Maven

Maven 翻译为"专家"、“内行”,是 Apache 下的一个纯 Java 开发的开源项目。基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。

Maven 是一个项目管理工具,可以对 Java 项目进行构建、依赖管理。

Maven 也可被用于构建和管理各种项目,例如 C#,Ruby,Scala 和其他语言编写的项目。Maven 曾是 Jakarta 项目的子项目,现为由 Apache 软件基金会主持的独立 Apache 项目。

2、Maven profiles 构建配置文件

pom.xml 可以定义 profilesprofiles 中包含多个 profile 可以让我们定义一系列的配置信息,然后指定其激活条件。这样我们就可以定义多个 profile,然后每个 profile 对应不同的激活条件和配置信息,从而达到不同环境使用不同配置信息的效果。

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>profile-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <name>profile-demo</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <profiles>
        <!--本地环境 -->
        <profile>
            <id>local</id>
            <properties>
                <activatedProperties>local</activatedProperties>
            </properties>
        </profile>
        <!--开发环境 -->
        <profile>
            <id>dev</id>
            <properties>
                <activatedProperties>dev</activatedProperties>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
        <!--测试环境 -->
        <profile>
            <id>test</id>
            <properties>
                <activatedProperties>test</activatedProperties>
            </properties>
        </profile>
        <!--uat 环境 -->
        <profile>
            <id>uat</id>
            <properties>
                <activatedProperties>uat</activatedProperties>
            </properties>
        </profile>
        <!--预发布环境 -->
        <profile>
            <id>pre</id>
            <properties>
                <activatedProperties>pre</activatedProperties>
            </properties>
        </profile>
        <!--生产环境 -->
        <profile>
            <id>prod</id>
            <properties>
                <activatedProperties>prod</activatedProperties>
            </properties>
        </profile>
    </profiles>

</project>

注意:构建配置文件采用的是 节点。

说明:上面新建了 6 个 <profile>,其中 <id>区分了不同的 <profile> 也就是构建添加不同的配置文件到项目当中,上面指定了默认的环境是 dev 也就是不通过命令指定那么默认就是 profile 就是 dev。此时构建配置文件起到了传输指定的作用,比如,通过命令行参数输入指定的 <id>

可以通过执行命令修改 profile:

mvn package -P prod

这个时候的环境就设置成了 prod 环境。

3、Spring Boot 集成 maven 多环境

Spring Boot 项目和 maven 多环境集成有两种模式,下面我们就来分别描述一下这两种方式是如何实现的吧。

3.1 Spring Boot Profiles 与 Maven Profiles 集成

spring 内部也有自己的 profile 定义,它是通过 spring.profiles.active 这个参数来指定的。关于它我就不做过多介绍了网上的帖子很多,大家可以自行了解。

3.1.1 pom 依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.5.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

    <groupId>org.example</groupId>
    <artifactId>profile-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <profiles>
        <!--本地环境 -->
        <profile>
            <id>local</id>
            <properties>
                <activatedProperties>local</activatedProperties>
            </properties>
        </profile>
        <!--开发环境 -->
        <profile>
            <id>dev</id>
            <properties>
                <activatedProperties>dev</activatedProperties>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
        <!--测试环境 -->
        <profile>
            <id>test</id>
            <properties>
                <activatedProperties>test</activatedProperties>
            </properties>
        </profile>
        <!--uat 环境 -->
        <profile>
            <id>uat</id>
            <properties>
                <activatedProperties>uat</activatedProperties>
            </properties>
        </profile>
        <!--预发布环境 -->
        <profile>
            <id>pre</id>
            <properties>
                <activatedProperties>pre</activatedProperties>
            </properties>
        </profile>
        <!--生产环境 -->
        <profile>
            <id>prod</id>
            <properties>
                <activatedProperties>prod</activatedProperties>
            </properties>
        </profile>
    </profiles>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>2.8.2</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

3.1.2 项目结构

App 类是一个简单的 Spring Boot 项目类,它在启动成功后会打印配置文件当中配置的 env 信息

3.1.3 不同的配置文件

application.properties

server.port=8888
spring.profiles.active=@activatedProperties@

里面配置了服务启动的端口,最重要的是配置通过配置spring.profiles.active=@activatedProperties@ 把 spring 定义的环境与 maven 中的 profiles 结合了起来。我们通过 mvn clean package -P profile 就能够指定生效的环境。比如我们的命令是 mvn clean package -P uat 就是 application-uat.properties 生效。

下面就是代表不同环境的配置文件:

application-dev.properties

env=dev

application-local.properties

env=local

application-pre.properties

env=pre

application-prod.properties

env=prod

application-test.properties

env=test

application-uat.properties

env=uat

3.1.4 项目打包

我们以 mvn clean package -P prod 打包为例,测试打包成功的是生产环境的配置生效。


我们通过 Java 反编译工具可以看到 applicaiton.properties 配置文件当中的 spring.profiles.active=@activatedProperties@ 变更成我们指定的生成环境 prod


然后我们再到 $project/taget目录里通过命令 java -jar profile-demo-1.0-SNAPSHOT.jar 运行 spring boot 项目。


说明我们项目当中的多环境生效的是我们指定的 prod 生产环境的配置。

3.2 Maven Profiles 直接指定资源文件

上面的方式是基于 Spring Boot 项目的特性,也有可能我们的项目并不是 Spring boot 项目。那么有没有通用的解决方案呢?答案是有的,我们可以通过 Maven Profiles 直接指定资源文件.

3.2.1 Pom 依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.5.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

    <groupId>org.example</groupId>
    <artifactId>profile-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <profiles>
        <!--本地环境 -->
        <profile>
            <id>local</id>
            <properties>
                <activatedProperties>local</activatedProperties>
            </properties>
            <build>
                <resources>
                    <resource>
                        <directory>
                            $project.basedir/src/main/resources/env/local
                        </directory>
                    </resource>
                </resources>
            </build>
        </profile>
        <!--开发环境 -->
        <profile>
            <id>dev</id>
            <properties>
                <activatedProperties>dev</activatedProperties>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <build>
                <resources>
                    <resource>
                        <directory>
                            $project.basedir/src/main/resources/env/dev
                        </directory>
                    </resource>
                </resources>
            </build>
        </profile>
        <!--测试环境 -->
        <profile>
            <id>test</id>
            <properties>
                <activatedProperties>test</activatedProperties>
            </properties>
            <build>
                <resources>
                    <resource>
                        <directory>
                            $project.basedir/src/main/resources/env/test
                        </directory>
                    </resource>
                </resources>
            </build>
        </profile>
        <!--uat 环境 -->
        <profile>
            <id>uat</id>
            <properties>
                <activatedProperties>uat</activatedProperties>
            </properties>
            <build>
                <resources>
                    <resource>
                        <directory>
                            $project.basedir/src/main/resources/env/uat
                        </directory>
                    </resource>
                </resources>
            </build>
        </profile>
        <!--预发布环境 -->
        <profile>
            <id>pre</id>
            <properties>
                <activatedProperties>pre</activatedProperties>
            </properties>
            <build>
                <resources>
                    <resource>
                        <directory>
                            $project.basedir/src/main/resources/env/pre
                        </directory>
                    </resource>
                </resources>
            </build>
        </profile>
        <!--生产环境 -->
        <profile>
            <id>prod</id>
            <properties>
                <activatedProperties>prod</activatedProperties>
            </properties>
            <build>

以上是关于Spring Boot 项目通过 Maven profiles 使用 -P 支持项目多环境配置打包的主要内容,如果未能解决你的问题,请参考以下文章

spring boot 实战 / mvn spring-boot:run 参数详解

Spring Boot(Maven)+Docker打包

第三章 Maven构建 Java Spring Boot Web项目

Spring Boot学习笔记之一:传统maven项目与采用spring boot项目区别

spring boot 学习一 springboot项目初步搭建

笔记:Spring Boot 项目构建与解析