Maven插件之portable-config-maven-plugin(不同环境打包)

大的项目组中,分开发环境,测试环境,生产环境等;不同环境的配置不同,或数据源,或服务器,或数据库等;

问题来了,如何使用Maven针对不同的环境来打包呢?

Maven提供了Profile的概念,用来解决此类问题,其原理很简单,就是使用变量替换;举个例子来说明,测试项目目录结构如下图所示:

Maven插件之portable-config-maven-plugin(不同环境打包)_第1张图片

比如开发环境和生产环境的数据库不同,db.properties配置文件内容如下:

[html]  view plain copy
  1. #测试库  
  2. db.url=192.10.2.168  
  3. db.username=dbtest  
  4. db.password=dbtest  
  5. #正式库  
  6. #db.url=192.20.1.11  
  7. #db.username=admin  
  8. #db.password=comfreesecurity  

默认开启测试环境;生产环境打包时,需要手动修改该配置文件. juvenxu说过,手动意味着低效率,高错误率!!

Maven提供的Profile功能,可解决以上问题:

1、在pom.xml文件中定义两个不同的Profile,分别定义开发环境和生产环境的数据库信息:

[html]  view plain copy
  1. <profiles>  
  2.     <profile>  
  3.         <id>kaifaid>  
  4.         <properties>  
  5.             <db.url>192.10.2.168db.url>  
  6.             <db.username>dbtestdb.username>  
  7.             <db.password>dbtestdb.password>  
  8.         properties>  
  9.     profile>  
  10.       
  11.     <profile>  
  12.         <id>shengchanid>  
  13.         <properties>  
  14.             <db.url>192.20.1.11db.url>  
  15.             <db.username>admindb.username>  
  16.             <db.password>comfreesecuritydb.password>  
  17.         properties>  
  18.     profile>  
  19. profiles>  

2、将原来的配置文件内容修改如下:

[html]  view plain copy
  1. db.url=${db.url}  
  2. db.username=${db.username}  
  3. db.password=${db.password}  

3、需要 开启资源文件过滤 ,代码如下:
[html]  view plain copy
  1. <resources>  
  2.     <resource>  
  3.         <directory>${project.basedir}/src/main/resourcesdirectory>  
  4.         <filtering>truefiltering>  
  5.     resource>  
  6. resources>  


添加true,允许使用变量替换资源文件;
4、使用Maven命令打包时,指定Profile进行打包,命令如下:

mvn package -Pkaifa

mvn package -Pshengchan

如此即可。


此命令用的多了,就会发现,两个环境必选其一,如果能设置其一个为默认开启,就不用每次都手动指定了,这个需求很现实,毕竟开发环境需要持续不断的编译、打包、部署等,而上线,则是一段时间才会运行一次的;因此,默认启用开发环境是最优的方案,Maven支持默认启用某个Profile,只需在内添加如下代码即可:

[html]  view plain copy
  1. <activation>  
  2.     <activeByDefault>trueactiveByDefault>  
  3. activation>  

此处需要注意:一旦显式指定某个Profile,则该配置无效!


在实际开发中使用以上方式操作时,自然而然的会提出以下的问题:假如配置文件的信息很多,那么Profile的内容会很臃肿,不便于管理,如果能将配置信息从Profile抽取出来,独立放置,再根据不同的Profile去调用,如此就更好了!

Maven针对以上需求,确实有解决方案,就是使用标签,针对不同的环境,使用不同的文件替换原来配置文件中的变量。

项目根目录下新建如下目录和文件:

Maven插件之portable-config-maven-plugin(不同环境打包)_第2张图片

db.properties问标准的属性文件,kaifa/db.properties和shengchan/db.properties文件内容分别如下:

[html]  view plain copy
  1. db.url=192.10.2.168  
  2. db.username=dbtest  
  3. db.password=dbtest  

[html]  view plain copy
  1. db.url=192.20.1.11  
  2. db.username=admin  
  3. db.password=confreesecurity  

将Profile中的属性信息抽取到了db.properties文件中,同时在Profile中添加部分,修改后的代码如下:

[html]  view plain copy
  1. <profiles>  
  2.     <profile>  
  3.         <id>kaifaid>  
  4.         <activation>  
  5.             <activeByDefault>trueactiveByDefault>  
  6.         activation>  
  7.         <build>  
  8.             <filters>  
  9.                 <filter>${basedir}/filters/kaifa/db.propertiesfilter>  
  10.             filters>  
  11.         build>  
  12.     profile>  
  13.       
  14.     <profile>  
  15.         <id>shengchanid>  
  16.         <build>  
  17.             <filters>  
  18.                 <filter>${basedir}/filters/shengchan/db.propertiesfilter>  
  19.             filters>  
  20.         build>  
  21.     profile>  
  22. profiles>  

添加了...部分,使用指定的文件内容替换原文件中的变量;

如此之后,使用Maven命令进行构建即可。

细心的人会发现,以上Profile中的filters部分,除了使用的目录名称不同之外,其他代码全部相同,重复!!!
如果再多几个环境的话,代码冗余可想而知,因此需要优化,其实方法很简单,还是使用变量替换,修改后的pom.xml文件内容如下:

[html]  view plain copy
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  3.   
  4.     <modelVersion>4.0.0modelVersion>  
  5.   
  6.     <groupId>com.testgroupId>  
  7.     <artifactId>ProfileartifactId>  
  8.     <version>0.0.1-SNAPSHOTversion>  
  9.       
  10.     <build>  
  11.         <resources>  
  12.             <resource>  
  13.                 <directory>${project.basedir}/src/main/resourcesdirectory>  
  14.                 <filtering>truefiltering>  
  15.             resource>  
  16.         resources>  
  17.         <filters>  
  18.             <filter>${basedir}/filters/${filters.env}/db.propertiesfilter>  
  19.         filters>  
  20.     build>  
  21.     <profiles>  
  22.         <profile>  
  23.             <id>kaifaid>  
  24.             <activation>  
  25.                 <activeByDefault>trueactiveByDefault>  
  26.             activation>  
  27.             <properties>  
  28.                 <filters.env>kaifafilters.env>  
  29.             properties>  
  30.         profile>  
  31.   
  32.         <profile>  
  33.             <id>shengchanid>  
  34.             <properties>  
  35.                 <filters.env>shengchanfilters.env>  
  36.             properties>  
  37.         profile>  
  38.     profiles>  
  39. project>  

使用-P参数时,会激活属性,从而使用指定的过滤文件进行变量替换。


其实,以上方式使用久了,还是会有些想法,既然用变量,也就是说,必须使用Maven命令之后,才能部署到Tomcat等服务器中,多次重复的操作,还是有相当多的时间浪费在maven命令上,尤其在改动很少的代码的情况下;
此时又会提出新的需求,能否在不使用maven命令的情况下即可进行日常开发;测试环境(或生产环境)打包时,使用Maven命令和-P参数指定环境进行打包呢?


很幸运,Juven Xu--国内Maven第一人--为我们提供了这样的一个插件portable-config-maven-plugin,使用该插件,可以在不改变原有代码的基础上,进行不同环境的打包。

------以下应该算作最佳实践了

portable-config-maven-plugin插件的原理是内容替换(而不是变量替换);

插件代码地址:https://github.com/juven/portable-config-maven-plugin,目前最新版本为1.1.4;
该插件使用方法如下:

假设src/main/resources/db.properties文件代码如下:

[html]  view plain copy
  1. database.jdbc.username=dev  
  2. database.jdbc.password=dev_pwd  

对于测试环境,创建一个属性替换文件src/main/portable/test.xml,代码如下:

[html]  view plain copy
  1. xml version="1.0" encoding="utf-8" ?>  
  2. <portable-config>  
  3.     <config-file path="WEB-INF/classes/db.properties">  
  4.         <replace key="database.jdbc.username">testreplace>  
  5.         <replace key="database.jdbc.password">test_pwdreplace>  
  6.     config-file>  
  7. portable-config>  

此文件为替换内容描述文件,标签的path属性的值是基于war包的相对路径,指需要被内容替换的文件;
配置portable-config-maven-plugin插件(该插件默认绑定到package声明周期):

[html]  view plain copy
  1. <plugin>  
  2.     <groupId>com.juvenxu.portable-config-maven-plugingroupId>  
  3.     <artifactId>portable-config-maven-pluginartifactId>  
  4.     <version>1.1.4version>  
  5.     <executions>  
  6.         <execution>  
  7.             <goals>  
  8.                 <goal>replace-packagegoal>  
  9.             goals>  
  10.         execution>  
  11.     executions>  
  12.     <configuration>  
  13.         <portableConfig>src/main/portable/test.xmlportableConfig>  
  14.     configuration>  
  15. plugin>  

或在命令行指定替换内容描述文件:mvn clean package -DportableConfig="src/main/portable/test.xml"
打包完成后,db.properties文件内容会被替换。


该插件目前支持的内容替换文件格式有:

.properties

[html]  view plain copy
  1. database.jdbc.username=dev  
  2. database.jdbc.password=dev_pwd  
  3. 使用  
  4. <replace key="database.jdbc.username">testreplace>  
  5. <replace key="database.jdbc.password">test_pwdreplace>  
  6. 替换为:  
  7. database.jdbc.username=test  
  8. database.jdbc.password=test_pwd  


.xml(xml元素和属性可以使用xPath进行替换)

[html]  view plain copy
  1. xml version="1.0" encoding="UTF-8"?>  
  2. <server>  
  3.     <port>8080port>  
  4.     <hosts>  
  5.         <host id="1">localhosthost>  
  6.         <host id="2">localhosthost>  
  7.     hosts>  
  8.     <mode value="debug" />  
  9. server>  
  10. 使用  
  11. <replace xpath="/server/port">80replace>  
  12. <replace xpath="//host/[@id='1']">192.168.1.1replace>  
  13. <replace xpath="//host/[@id='2']">192.168.1.2replace>  
  14. <replace xpath="/server/mode/@value">runreplace>  
  15. 替换为:  
  16. xml version="1.0" encoding="UTF-8"?>  
  17. <server>  
  18.     <port>80port>  
  19.     <hosts>  
  20.         <host id="1">192.168.1.1host>  
  21.         <host id="2">192.168.1.2host>  
  22.     hosts>  
  23.     <mode value="run"/>  
  24. server>  


.sh

[html]  view plain copy
  1. 无引号、单引号、双引号、输出的shell变量可被替换  
  2. BIN_HOME=/tmp/bin  
  3. OUT_HOME="/tmp/out"  
  4. LOG_HOME='/tmp/log'  
  5. export APP_HOME="/tmp/app"  
  6. 使用  
  7. <replace key="BIN_HOME">/home/juven/binreplace>  
  8. <replace key="OUT_HOME">/home/juven/outreplace>  
  9. <replace key="LOG_HOME">/home/juven/logreplace>  
  10. <replace key="APP_HOME">/home/juven/appreplace>  
  11. 替换为:  
  12. BIN_HOME=/home/juven/bin  
  13. OUT_HOME="/home/juven/out"  
  14. LOG_HOME='/home/juven/log'  
  15. export APP_HOME="/home/juven/app"  


类似.properties格式

[html]  view plain copy
  1. 假如有个key=value类型的配置文件,但扩展名不是.properties,可按照以下方式指定:  
  2. xml version="1.0" encoding="utf-8" ?>  
  3. <portable-config>  
  4.     <config-file path="db.ini" type=".properties">  
  5.         <replace key="mysql.host">192.168.1.100replace>  
  6.     config-file>  
  7. portable-config>  
  8. 使用type属性强制指定文件类型。  


对该插件的介绍到此为止。

回头看看,发现内容和标题不符,说是介绍portable-config-maven-plugin插件,

却花了大篇幅的内容介绍了Maven其他的标签使用,不过以上内容总有相同之处--针对不同环境打包的一些解决方法

你可能感兴趣的:(Maven)