title: Apache Maven实现不同环境差异化编译和配置
date: 2022-03-31 00:00:00
tags:
- Apache Maven
- 配置
- 环境
categories: - Maven
背景
- 在实际软件项目开发中,项目需要经过不同环境验证通过后才能上线,而每个环境都有不同的配置参数,如何管理这些不同环境的配置数据对于项目开发和部署均至关重要。
- 在 Apache Maven 中是可以实现这个需求的,接下来介绍具体的实施过程。
在 POM.xml 文件中增加 profile 元素配置
<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 构建时将被替换。
spring:
application:
name: demo-1
profiles:
active: @spring.profiles.active@
上面利用了Spring的多配置文件切换功能,也就是说在resources目录应该存在下面的文件。
application.yml
application-local.yml
application-dev.yml
application-test.yml
application-staging.yml
application-production.yml
启动资源过滤,以替换动态变量
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
不同环境切换配置
- 在IDEA中可以手动切换,由于配置了
<activeByDefault>true</activeByDefault>
,所以dev profile默认是选中的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i1pAR2a5-1675530634199)(/images/maven_profiles.png)]
- 在编译时为特定环境打包,可以使用
-P
选项,例如为test环境打包:mvn -Ptest -DskipTests=true package
。 - 此时可以检查打包的jar,查看application.yml中的动态变量是否已经被替换。
扩展
上面利用了Spring自带的多配置文件切换功能,通过动态改变文件名称后缀来达到Spring仅加载特定配置之目的,那如果项目中没有使用Spring,单纯靠Maven是否也能管理多环境配置差异?
答案是可以的,因为你可以在 profiles.[].profile.properties
元素下面增加这些差异属性,例如:
<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来加载环境变量,从而屏蔽掉环境差异。