Maven 使用 Profile 构建

上一节,我们讲到了如何使用 Maven 自动化的进行单元测试,那测试通过之后,我们就要进行构建,并且将构建好的程序包,放到对应的服务器上去运行。这个时候,问题就出现了,对于不同环境,我们需要不同的配置文件,那我们构建的之前,就需要将配置文件改为对应环境的配置文件,之后才能进行构建。总而言之,很麻烦,而且,万一忘记改配置,那么构建出来的包就是错的。

Profile 则让不同环境之间可移植性的构建成为可能。它使我们在构建项目的时候,可以很轻松的在不同环境中进行构建,也可以称之为“开箱即用”。

1. 可移植性

首先,我们来介绍一下可移植性。所谓的可移植性,指的是,在构建的过程中,改动配置文件的次数和范围越小,则可移植性越强,反之,则可移植性越弱。根据可移植性的不同程度,我们可以将其划分为如下几类:

  • 不可移植: 指的是,项目只能在某个特定环境或者条件下才能构建。这种时候,构建是不可移植的,当然,我们在开发的过程中,肯定是不想看到这种情况的发生。

  • 环境可移植: 指的是,对于不同环境添加不同的配置,一次构建都能够完成,那么这个构建就具备环境可移植了。即:无需对不同环境做过多改动,即可完成相应构建。

  • 全局可移植: 指的是,无论在何种环境下,开发者都不需要做任何配置,即可完成对项目的构建工作。这个特性对于优秀的开源软件来说,尤其重要。因为这种类型的软件,往往会由来自各地的开发者来共同开发。

在大多数情况下,我们平时开发的项目只需要做到环境可移植就可以了。因为通常的公司往往会有三套环境,开发环境,测试环境,生产环境,针对不同的开发阶段,往往需要将项目构建到不同的环境中去,但是由于这些项目通常部署在公司的内网环境中,所以,我们并不需要考虑做到全局可移植性。

2. Maven Profile

在了解了什么是可移植性之后,那我们来看看 Maven 是如何实现可移植性的。这里就需要介绍 Maven 的一组配置 Profile 。通过使用 Profile 我们就可以实现针对不同环境自定义进行构建。通常情况下,Profile 被定义在 pom.xml 文件中,但是定义的方式也可以有很多种。

<profiles>
   <profile>
        <id>dev</id>
        <properties>
            <database.driver>com.mysql.cj.jdbc.Driver</database.driver>
            <database.url>jdbc:mysql://localhost:3306/dev</database.url>
            <database.username>Mic</database.username>
            <database.password>Abc123</database.password>
        </properties>
    </profile>
    <profile>
        <id>test</id>
        <properties>
            <database.driver>com.mysql.cj.jdbc.Driver</database.driver>
            <database.url>jdbc:mysql://localhost:3306/test</database.url>
            <database.username>Mic</database.username>
            <database.password>Abc123</database.password>
        </properties>
     </profile>
</profiles>

这里我们以数据库连接串为例,可以将不同环境中的数据库连接串配置到对应的 profile 节点中,并为每个 profile 节点定义单独的 id 。配置好之后,我们我们在进行构建项目的时候,可以在执行命令的时候,加上参数 -Pdev 来指定对应的配置 :mvn clean package -Pdev

但是问题来了,通常情况下,我们不会把配置信息放到 pom.xml 文件中,这样对于我们管理配置,并不方便。那我们如何在构建的时候,指定使用对应的配置文件来进行构建呢?我们可以对 pom.xml 文件进行简单的修改。

<build>
    <finalName>mall-order</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
            	<executable>true</executable>
            </configuration>
        </plugin>
    </plugins>

    <resources>
        <resource>
        	<directory>src/main/resources/</directory>
        	<!-- 打包时,将对应配置文件先排除 -->
            <excludes>
            	<exclude>**/*.yml</exclude>
            </excludes>
            <includes>
            <!--如果有其他定义通用文件,需要包含进来-->
            </includes>
        </resource>
        <resource>
            <!-- 通过自定义的节点来激活指定的配置文件 -->
            <directory>src/main/resources/${profile.active}</directory>
        </resource>
    </resources>
</build>

<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <!-- 自定义节点profile.active-->
            <profile.active>dev</profile.active>
        </properties>
        <!--activation用来指定激活方式,可以根据jdk环境,环境变量,文件的存在或缺失-->
        <activation>
            <!-- 表示默认激活-->
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>test</id>
        <properties>
        	<profile.active>test</profile.active>
        </properties>
    </profile>
</profiles>

首先,我们定义 resource 节点用于指定配置文件的目录,并将最后一级目录定义成可配置的。然后,跟刚刚类似,我们开始定义 profiles 节点,只不过这次,我们只是在 properties 节点中自定义了一个节点,与 resource 中的自定义路径相呼应。相应的,我们需要在 resources目录下,创建两个目录,分别为 dev 和 prod 目录,用于存放不同的配置文件。

都配置好之后,我们再使用命令 mvn clean package -Pdev 来构建项目。构建完成后,我们查看目录targetclasses 会发现,application-dev.yml 配置文件被编译进来,而另一个配置文件并没有被编译进来。这时候,我们的基本上就达成 了。

注意:由于我们这里配置的 dev Profile 是默认激活状态的,所以执行 mvn clean packagemvn clean package -Pdev 两个命令的结果是相同的。

当然,通过配置 profile ,我们不仅仅可以指定激活不同的配置文件,也可以指定构建使用的JDK版本,以及某些操作系统的参数。

3. 小结

本节中,我们主要介绍了 Maven 的一个属性,叫做 Profile 。通过配置 Profile 我们可以实现构建的环境可移植性,从而大大简化我们在构建过程中的便捷程度,让我们从重复的修改配置的过程中解脱出来。