在大型的项目组中,分不同的开发环境,测试环境,生产环境(说白了就是配置文件不同,或者数据源,或者服务器,或者数据库等);问题来了,如何使用Maven针对不同的环境来打包呢?
Maven提供了Profile的概念,用来解决此类问题,其原理很简单,就是使用变量替换;举个例子来说明,测试项目目录结构如下图所示:
比如开发环境和生产环境的数据库不同,db.properties配置文件内容如下:
#测试库
db.url=192.10.2.168
db.username=dbtest
db.password=dbtest
#正式库
#db.url=192.20.1.11
#db.username=admin
#db.password=comfreesecurity
生产环境打包时,需要手动修改该配置文件;juvenxu说过,手动意味着低效率,高错误率!!
使用Profile时,以上情况可简化如下:
1、在pom.xml文件中定义两个不同的Profile,分别定义开发环境和生产环境的数据库信息:
<profiles>
<profile>
<id>kaifa</id>
<properties>
<db.url>192.10.2.168</db.url>
<db.username>dbtest</db.username>
<db.password>dbtest</db.password>
</properties>
</profile>
<profile>
<id>shengchan</id>
<properties>
<db.url>192.20.1.11</db.url>
<db.username>admin</db.username>
<db.password>comfreesecurity</db.password>
</properties>
</profile>
</profiles>
2、将原来的配置文件内容修改如下:
db.url=${db.url}
db.username=${db.username}
db.password=${db.password}
3、需要 开启资源文件过滤 ,代码如下:
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
添加 <filtering>true</filtering> ,允许使用变量替换资源文件; 4、使用Maven命令打包时,指定Profile进行打包,命令如下:
mvn package -Pkaifa
mvn package -Pshengchan
如此即可。
此命令用的多了,就会发现,两个环境必选其一,如果能设置其一个为默认开启,就不用每次都手动指定了,这个需求很现实,毕竟开发环境需要持续不断的编译、打包、部署等,而上线,则是一段时间才会运行一次的;因此,默认启用开发环境是最优的方案,Maven支持默认启用某个Profile,只需在<profile>内添加如下代码即可:
<activation>
<activeByDefault>true</activeByDefault>
</activation>
此处需要注意:一旦显式指定某个Profile,则该配置无效! 在实际开发中使用以上方式操作时,自然而然的会提出以下的问题:假如配置文件的信息很多,那么Profile的内容会很臃肿,不便于管理,如果能将配置信息从Profile抽取出来,独立放置,再根据不同的Profile去调用,如此就更好了!
Maven针对以上需求,确实有解决方案,就是使用<filters>标签,针对不同的环境,使用不同的文件替换原来配置文件中的变量。
项目根目录下新建如下目录和文件:
db.properties问标准的属性文件,kaifa/db.properties和shengchan/db.properties文件内容分别如下:
db.url=192.10.2.168
db.username=dbtest
db.password=dbtest
db.url=192.20.1.11
db.username=admin
db.password=comfreesecurity
将Profile中的属性信息抽取到了db.properties文件中,同时在Profile中添加<filters></filters>部分,修改后的代码如下:
<profiles> <profile> <id>kaifa</id> <activation> <activeByDefault>true</activeByDefault> </activation> <build> <filters> <filter>${basedir}/filters/kaifa/db.properties</filter> </filters> </build> </profile> <profile> <id>shengchan</id> <build> <filters> <filter>${basedir}/filters/shengchan/db.properties</filter> </filters> </build> </profile> </profiles>
添加了 <filters><filter>...</filter></filters> 部分,使用指定的文件内容替换原文件中的变量;
如此之后,使用Maven命令进行构建即可。
细心的人会发现,以上Profile中的filters部分,除了使用的目录名称不同之外,其他代码全部相同,重复!!!
如果再多几个环境的话,代码冗余可想而知,因此需要优化,其实方法很简单,还是使用变量替换,修改后的pom.xml文件内容如下:
<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>com.test</groupId>
<artifactId>Profile</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<filters>
<filter>${basedir}/filters/${filters.env}/db.properties</filter>
</filters>
</build>
<profiles>
<profile>
<id>kaifa</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<filters.env>kaifa</filters.env>
</properties>
</profile>
<profile>
<id>shengchan</id>
<properties>
<filters.env>shengchan</filters.env>
</properties>
</profile>
</profiles>
</project>
使用-P参数时,会激活<filters.env>属性,从而使用指定的过滤文件进行变量替换。
其实,以上方式使用久了,还是会有些想法,既然用变量,也就是说,必须使用Maven命令之后,才能部署到Tomcat等服务器中,多次重复的操作,还是有相当多的时间浪费在maven命令上,尤其在改动很少的代码的情况下;
此时又会提出新的需求,能否在不使用maven命令的情况下即可进行日常开发;测试环境(或生产环境)打包时,使用Maven命令和-P参数指定环境进行打包呢?
很幸运,Juven Xu--国内Maven第一人--为我们提供了这样的一个插件 portable-config-maven-plugin ,使用该插件,可以在不改变原有代码的基础上,进行不同环境的打包;其原理是使用内容替换(而不是变量替换);
插件代码地址: https://github.com/juven/portable-config-maven-plugin ,目前最新版本为1.1.4;
该插件使用方法如下:
假设 src/main/resources/db.properties 文件代码如下:
database.jdbc.username=dev
database.jdbc.password=dev_pwd
对于测试环境,创建一个属性替换文件 src/main/portable/test.xml ,代码如下: <?xml version="1.0" encoding="utf-8" ?>
<portable-config>
<config-file path="WEB-INF/classes/db.properties">
<replace key="database.jdbc.username">test</replace>
<replace key="database.jdbc.password">test_pwd</replace>
</config-file>
</portable-config>
此文件为替换内容描述文件,<config-file>标签的 path 属性的值是基于war包的 相对路径 ,指需要被内容替换的文件 ; 配置portable-config-maven-plugin插件( 该插件默认绑定到package声明周期 ):
<plugin>
<groupId>com.juvenxu.portable-config-maven-plugin</groupId>
<artifactId>portable-config-maven-plugin</artifactId>
<version>1.1.4</version>
<executions>
<execution>
<goals>
<goal>replace-package</goal>
</goals>
</execution>
</executions>
<configuration>
<portableConfig>src/main/portable/test.xml</portableConfig>
</configuration>
</plugin>
或在命令行指定替换内容描述文件:mvn clean package -DportableConfig="src/main/portable/test.xml"
打包完成后,db.properties文件内容会被替换。
该插件目前支持的内容替换文件格式有:
.properties
database.jdbc.username=dev
database.jdbc.password=dev_pwd
使用 <replace key="database.jdbc.username">test</replace>
<replace key="database.jdbc.password">test_pwd</replace>
替换为: database.jdbc.username=test
database.jdbc.password=test_pwd
.xml
xml元素和属性可以使用xPath进行替换
<?xml version="1.0" encoding="UTF-8"?>
<server>
<port>8080</port>
<hosts>
<host id="1">localhost</host>
<host id="2">localhost</host>
</hosts>
<mode value="debug" />
</server>
使用 <replace xpath="/server/port">80</replace>
<replace xpath="//host/[@id='1']">192.168.1.1</replace>
<replace xpath="//host/[@id='2']">192.168.1.2</replace>
<replace xpath="/server/mode/@value">run</replace>
替换为: <?xml version="1.0" encoding="UTF-8"?>
<server>
<port>80</port>
<hosts>
<host id="1">192.168.1.1</host>
<host id="2">192.168.1.2</host>
</hosts>
<mode value="run"/>
</server>
.sh 无引号、单引号、双引号、输出的shell变量可被替换
BIN_HOME=/tmp/bin
OUT_HOME="/tmp/out"
LOG_HOME='/tmp/log'
export APP_HOME="/tmp/app"
使用 <replace key="BIN_HOME">/home/juven/bin</replace>
<replace key="OUT_HOME">/home/juven/out</replace>
<replace key="LOG_HOME">/home/juven/log</replace>
<replace key="APP_HOME">/home/juven/app</replace>
替换为: BIN_HOME=/home/juven/bin
OUT_HOME="/home/juven/out"
LOG_HOME='/home/juven/log'
export APP_HOME="/home/juven/app"
假如有个key=value类型的配置文件,但扩展名不是.properties,可按照以下方式指定: <?xml version="1.0" encoding="utf-8" ?>
<portable-config>
<config-file path="db.ini" type=".properties">
<replace key="mysql.host">192.168.1.100</replace>
</config-file>
</portable-config>
使用 type 属性强制指定文件类型。 对该插件的介绍到此为止。
回头看看,发现内容和标题不符,说是介绍portable-config-maven-plugin插件,却花了大篇幅的内容介绍了Maven其他的标签使用,不过以上内容总有相同之处-- 针对不同环境打包的一些解决方法 。
相关推荐
Maven 使用 tomcat8-maven-plugin 插件 Maven 是一个流行的构建自动化工具,它可以帮助开发者自动完成项目的编译、测试、打包、部署等任务。 Tomcat 是一个流行的 Web 服务器,Maven 提供了一个插件 tomcat8-maven-...
Maven-assembly-plugin是maven中针对打包任务而提供的标准插件,可以实现自定义打包。主要提供如下功能: ● 提供一个把工程依赖元素、模块、网站文档等其他文件存放到单个归档文件里。 ● 打包成指定格式分发包,...
本文详细介绍了exec-maven-plugin的基本概念、配置方法、执行简单和系统脚本、捕获命令输出、条件执行、并发执行、使用环境变量、错误处理、高级配置、使用案例以及局限性。通过这些知识点,读者可以更加自信地在...
例如,`maven-compiler-plugin` 是一个非常重要的插件,用于编译项目的源代码。它负责将 Java 源代码编译为字节码,这是软件开发过程中的关键步骤。 ** maven-compiler-plugin-3.8.0-source-release 插件** `maven...
maven-deploy-plugin-2.8.2.jar
maven3-plugin-3.0.1-sources.jar
总的来说,`maven-assembly-plugin`是Maven构建过程中的一个重要工具,它帮助开发者灵活地定制打包过程,适应不同环境的需求。结合Spring Boot项目,我们可以更高效地管理和部署应用程序,提高开发和运维的效率。
maven-jar-plugin-3.1.1.jar
maven-plantuml-plugin, 使用PlantUML语法生成UML图的Maven 插件 然而,这个项目不再被维护了。使用语法生成UML图表的一个 Maven 插件插件。重要说明如果你想使用PlantUML大于 8031的版本,你必须使用这个插件的版本...
maven-site-plugin-3.3.jar
<artifactId>spring-boot-maven-plugin </plugin> ``` 继承 Starter 父 POM Spring Boot 提供了一个 Starter 父 POM,用于简化 Spring Boot 项目的构建过程。该 POM 包含了许多有用的依赖项和配置,例如 ...
解决tomcat8-maven-plugin-3.0-r1655215.jar阿里云同有的问题。放到路径org\apache\tomcat\maven\tomcat8-maven-plugin\3.0-r1655215\就可以了
ECLIPSE MAVEN3插件文件(eclipse-maven3-plugin工具)
maven-project-info-reports-plugin-2.1.jar
maven-antrun-plugin-1.3.jar maven-archiver-2.2.jar maven-artifact-3.2.1-sources.jar maven-assembly-plugin-2.2-beta-5.jar maven-bundle-plugin-1.0.0.jar maven-clean-plugin-2.4.1.jar maven-clean-plugin-...
maven3-plugin-3.0.0-1-sources.jar
maven-surefire-plugin-2.22.1.jar
本文将详细讨论如何将Jetty与Maven进行集成,并介绍关键的`maven-jetty-plugin`插件及其不同版本。 1. Maven与Jetty集成的意义: Maven通过其强大的依赖管理功能,使得项目构建变得简单和规范。而Jetty作为轻量级...
maven-clean-plugin-3.1.0.jar
maven-jar-plugin-2.6.jar。解决maven官网上下载不下来或者下载速度慢的问题。