架构师修炼之道

知识日新月异,唯有保持同步迭代,才能适应美好的未来!

0%

Apache Maven实现不同环境差异化编译和配置

背景

  • 在实际软件项目开发中,项目需要经过不同环境验证通过后才能上线,而每个环境都有不同的配置参数,如何管理这些不同环境的配置数据对于项目开发和部署均至关重要。
  • Apache Maven 中是可以实现这个需求的,接下来介绍具体的实施过程。

在 POM.xml 文件中增加 profile 元素配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<spring.profiles.active>dev</spring.profiles.active>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<spring.profiles.active>test</spring.profiles.active>
</properties>
</profile>
<profile>
<id>staging</id>
<properties>
<spring.profiles.active>staging</spring.profiles.active>
</properties>
</profile>
<profile>
<id>production</id>
<properties>
<spring.profiles.active>production</spring.profiles.active>
</properties>
</profile>
</profiles>

在 application.yml 配置文件中增加动态变量

下面的动态变量由前后 @ 符号包裹,在 maven 构建时将被替换。

1
2
3
4
5
spring:
application:
name: demo-1
profiles:
active: @spring.profiles.active@

上面利用了Spring的多配置文件切换功能,也就是说在resources目录应该存在下面的文件。

1
2
3
4
5
6
application.yml
application-local.yml
application-dev.yml
application-test.yml
application-staging.yml
application-production.yml

启动资源过滤,以替换动态变量

1
2
3
4
5
6
7
8
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>

不同环境切换配置

  • 在IDEA中可以手动切换,由于配置了 <activeByDefault>true</activeByDefault>,所以dev profile默认是选中的。

  • 在编译时为特定环境打包,可以使用 -P 选项,例如为test环境打包:mvn -Ptest -DskipTests=true package
  • 此时可以检查打包的jar,查看application.yml中的动态变量是否已经被替换。

扩展

上面利用了Spring自带的多配置文件切换功能,通过动态改变文件名称后缀来达到Spring仅加载特定配置之目的,那如果项目中没有使用Spring,单纯靠Maven是否也能管理多环境配置差异?

答案是可以的,因为你可以在 profiles.[].profile.properties 元素下面增加这些差异属性,例如:

1
2
3
4
5
6
7
8
9
10
11
<profile>
<id>test</id>
<properties>
<spring.profiles.active>test</spring.profiles.active>
<mysql.url>jdbc:mysql://127.0.0.1:3306/test</mysql.url>
<mysql.username>root</mysql.username>
<redis.host>127.0.0.1</redis.host>
<rocketmq.servers>127.0.0.1:9876</rocketmq.servers>
<...>...</...>
</properties>
</profile>

最后补充:其实不用Maven,单纯使用Spring读取环境变量的功能,也能够达到我们的目的,例如在k8s环境配置ConfigMap来加载环境变量,从而屏蔽掉环境差异。


源码下载