最近项目中需要引入一个叫做ABTest工具。看了一下官方给出的文档,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <!-- abtest 配置 --> <filter> <filter-name>AbtestFilter</filter-name> <filter-class >com .******************.*********.web .DefaultTestFilter </filter -class > <init -param > <param -name >env </param -name > <param-value>${env}</param-value> </init-param> <init-param> <param-name>appName</param-name> <param-value>demo</param-value> </init-param> </filter> <filter-mapping> <filter-name>AbtestFilter</filter-name> <url-pattern>*.htm</url-pattern> </filter-mapping> <filter-mapping> <filter-name>AbtestFilter</filter-name> <url-pattern>
可以看到其中${env}
的变量值是需要进行动态替换的。一开始我觉得可以使用maven-war-plugin
来完成这个配置,BUT NOT WORK FOR ME!绕了好久的弯,终于看到了项目中进行config.properties
替换使用的一个插件maven-antrun-plugin
,BINGO,替换成功!
先进行一下说明,项目中并没有使用antx来进行配置,因此适用于antx的方案不一定适合本项目,所以一开始就没有往antx的方向考虑。
使用maven-war-plugin进行替换[❌] 看了一下父pom的配置,发现它使用了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 <profile > <id > staging</id > <properties > <env > staging</env > <ant-properties-path > src/main/resources/conf/config-staging.properties</ant-properties-path > </properties > </profile > <profile > <id > publish</id > <properties > <env > publish</env > <ant-properties-path > src/main/resources/conf/config-pro.properties</ant-properties-path > </properties > </profile > <profile > <id > production</id > <properties > <env > production</env > <ant-properties-path > src/main/resources/conf/config-pro.properties</ant-properties-path > </properties > <activation > <activeByDefault > true</activeByDefault > </activation > </profile >
可以看到不同的环境有不同的配置文件。在profile
中添加一个属性test-env
,如下:
1 2 3 4 5 6 7 8 9 10 11 12 <profile > <id > production</id > <properties > <env > production</env > <test-env > online</test-env > <ant-properties-path > src/main/resources/conf/config-pro.properties</ant-properties-path > </properties > <activation > <activeByDefault > true</activeByDefault > </activation > </profile >
然后再在webapp子pom中进行maven-war-plugin
插件的配置,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <plugin > <groupId > org.apache.maven.plugins</groupId > <artifactId > maven-war-plugin</artifactId > <configuration > <webResources > <resource > <directory > ${basedir}/src/main/webapp</directory > <excludes > <exclude > **/.svn</exclude > </excludes > <includes > <include > **/web.xml</include > </includes > </resource > </webResources > <webXml > ${basedir}/src/main/webapp/WEB-INF/web.xml</webXml > <warSourceDirectory > ${basedir}/src/main/webapp</warSourceDirectory > </configuration > </plugin >
然后使用maven命令进行构建,mvn clean package -Dmaven.test.skip=true -Pproduction
,但是生成war包以后,进入WEB-INF目录一看,发现这个根本就没有进行替换。NOT WORK FOR ME!
说明
这个方法我觉得理论上应该是可以的,如果有更好的建议或者我的描述有不对的地方欢迎指出来哈!非常感谢!
使用maven-antrun-plugin进行替换[✔️] 后面研究了一下config.properties
是如何实现多套环境的替换的,终于在同一个文件,也就是webapp子pom里面找到了答案,它使用了maven-antrun-plugin
进行运行时构建,具体的替换逻辑如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <plugin > <artifactId > maven-antrun-plugin</artifactId > <version > 1.8</version > <executions > <execution > <id > configReplace</id > <phase > validate</phase > <goals > <goal > run</goal > </goals > <configuration > <tasks > <copy file ="${ant-properties-path}" tofile ="${project.build.directory}/classes/config.properties" /> </tasks > </configuration > </execution > </executions > </plugin >
进入查看tasks
标签的描述,如下:
1 2 3 4 5 6 7 8 9 <parameter > <name > tasks</name > <type > org.apache.tools.ant.Target</type > <required > false</required > <editable > true</editable > <description > The XML for the Ant task. You can add anything you can add between &lt;target&gt; and &lt;/target&gt; in a build.xml. </description > </parameter >
具体的意思是说我们可以在build.xml
文件中的<target>
标签内添加任何任务。我找了一下build.xml
的基本demo,如下:
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 <?xml version="1.0" encoding="UTF-8" ?> <project name ="AntTestDemo" default ="run" basedir ="." > <property name ="src" value ="src" /> <property name ="dest" value ="classes" /> <property name ="helloant_jar" value ="helloant.jar" /> <target name ="init" > <mkdir dir ="${dest}" /> </target > <target name ="compile" depends ="init" > <javac srcdir ="${src}" destdir ="${dest}" /> </target > <target name ="build" depends ="compile" > <jar jarfile ="${helloant_jar}" basedir ="${dest}" /> </target > <target name ="run" depends ="build" > <java classname ="com.zdz.ant.test.HelloAnt" classpath ="${helloant_jar}" /> </target > <target name ="clean" > <delete dir ="${dest}" /> <delete file ="${helloant_jar}" /> </target > <target name ="rerun" depends ="clean,run" > <ant target ="clean" /> <ant target ="run" /> </target > </project >
我发现这些target
下面的标签不正是一些常见的命令吗?这个太强大了!因此,我想到可不可以使用一个替换命令,直接使用profile
中定义的属性直接进行web.xml
中的属性替换。上网一查,果然有同学这样做过,BINGO!我果断在webapp子pom中添加一个execution
任务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <execution > <id > envReplace</id > <phase > package</phase > <goals > <goal > run</goal > </goals > <configuration > <tasks > <replace file ="${project.build.directory}/demo/WEB-INF/web.xml" token ="defaultTestEnv" value ="${test-env}" /> </tasks > </configuration > </execution >
web.xml文件中要替换的地方如下:
1 2 3 4 5 6 7 8 9 10 11 12 <filter > <filter-name > teslaFilter</filter-name > <filter-class > com.******************.*********.web.DefaultTestFilter</filter-class > <init-param > <param-name > env</param-name > <param-value > defaultTestEnv</param-value > </init-param > <init-param > <param-name > appName</param-name > <param-value > demo</param-value > </init-param > </filter >
然后再重新打包,果然OK了。
总结 这个动态替换的问题确实会困扰到很多同学,至少困扰了我半个下午来解决这个问题,在这里记录一下,和大家分享这个问题的一种解决思路。