上一节,我们讲到了如何使用 Maven 自动化的进行单元测试,那测试通过之后,我们就要进行构建,并且将构建好的程序包,放到对应的服务器上去运行。这个时候,问题就出现了,对于不同环境,我们需要不同的配置文件,那我们构建的之前,就需要将配置文件改为对应环境的配置文件,之后才能进行构建。总而言之,很麻烦,而且,万一忘记改配置,那么构建出来的包就是错的。
Profile 则让不同环境之间可移植性的构建成为可能。它使我们在构建项目的时候,可以很轻松的在不同环境中进行构建,也可以称之为“开箱即用”。

1. 可移植性

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

  • 不可移植: 指的是,项目只能在某个特定环境或者条件下才能构建。这种时候,构建是不可移植的,当然,我们在开发的过程中,肯定是不想看到这种情况的发生。
  • 环境可移植: 指的是,对于不同环境添加不同的配置,一次构建都能够完成,那么这个构建就具备环境可移植了。即:无需对不同环境做过多改动,即可完成相应构建。
  • 全局可移植: 指的是,无论在何种环境下,开发者都不需要做任何配置,即可完成对项目的构建工作。这个特性对于优秀的开源软件来说,尤其重要。因为这种类型的软件,往往会由来自各地的开发者来共同开发。

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

2. Maven Profile

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

  1. <profiles>
  2. <profile>
  3. <id>dev</id>
  4. <properties>
  5. <database.driver>com.mysql.cj.jdbc.Driver</database.driver>
  6. <database.url>jdbc:mysql://localhost:3306/dev</database.url>
  7. <database.username>Mic</database.username>
  8. <database.password>Abc123</database.password>
  9. </properties>
  10. </profile>
  11. <profile>
  12. <id>test</id>
  13. <properties>
  14. <database.driver>com.mysql.cj.jdbc.Driver</database.driver>
  15. <database.url>jdbc:mysql://localhost:3306/test</database.url>
  16. <database.username>Mic</database.username>
  17. <database.password>Abc123</database.password>
  18. </properties>
  19. </profile>
  20. </profiles>

这里我们以数据库连接串为例,可以将不同环境中的数据库连接串配置到对应的 profile 节点中,并为每个 profile 节点定义单独的 id 。配置好之后,我们我们在进行构建项目的时候,可以在执行命令的时候,加上参数 -Pdev 来指定对应的配置 :mvn clean package -Pdev。
但是问题来了,通常情况下,我们不会把配置信息放到 pom.xml 文件中,这样对于我们管理配置,并不方便。那我们如何在构建的时候,指定使用对应的配置文件来进行构建呢?我们可以对 pom.xml 文件进行简单的修改。

  1. <build>
  2. <finalName>mall-order</finalName>
  3. <plugins>
  4. <plugin>
  5. <groupId>org.springframework.boot</groupId>
  6. <artifactId>spring-boot-maven-plugin</artifactId>
  7. <configuration>
  8. <executable>true</executable>
  9. </configuration>
  10. </plugin>
  11. </plugins>
  12. <resources>
  13. <resource>
  14. <directory>src/main/resources/</directory>
  15. <!-- 打包时,将对应配置文件先排除 -->
  16. <excludes>
  17. <exclude>**/*.yml</exclude>
  18. </excludes>
  19. <includes>
  20. <!--如果有其他定义通用文件,需要包含进来-->
  21. </includes>
  22. </resource>
  23. <resource>
  24. <!-- 通过自定义的节点来激活指定的配置文件 -->
  25. <directory>src/main/resources/${profile.active}</directory>
  26. </resource>
  27. </resources>
  28. </build>
  29. <profiles>
  30. <profile>
  31. <id>dev</id>
  32. <properties>
  33. <!-- 自定义节点profile.active-->
  34. <profile.active>dev</profile.active>
  35. </properties>
  36. <!--activation用来指定激活方式,可以根据jdk环境,环境变量,文件的存在或缺失-->
  37. <activation>
  38. <!-- 表示默认激活-->
  39. <activeByDefault>true</activeByDefault>
  40. </activation>
  41. </profile>
  42. <profile>
  43. <id>test</id>
  44. <properties>
  45. <profile.active>test</profile.active>
  46. </properties>
  47. </profile>
  48. </profiles>

首先,我们定义 resource 节点用于指定配置文件的目录,并将最后一级目录定义成可配置的。然后,跟刚刚类似,我们开始定义 profiles 节点,只不过这次,我们只是在 properties 节点中自定义了一个节点,与 resource 中的自定义路径相呼应。相应的,我们需要在 resources目录下,创建两个目录,分别为 dev 和 prod 目录,用于存放不同的配置文件。
Maven 使用 Profile 构建 - 图1
都配置好之后,我们再使用命令 mvn clean package -Pdev 来构建项目。构建完成后,我们查看目录target\classes 会发现,application-dev.yml 配置文件被编译进来,而另一个配置文件并没有被编译进来。这时候,我们的基本上就达成 了。
注意:由于我们这里配置的 dev Profile 是默认激活状态的,所以执行 mvn clean package 和 mvn clean package -Pdev 两个命令的结果是相同的。
Maven 使用 Profile 构建 - 图2
当然,通过配置 profile ,我们不仅仅可以指定激活不同的配置文件,也可以指定构建使用的JDK版本,以及某些操作系统的参数。

3. 小结

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