zoukankan      html  css  js  c++  java
  • Maven插件之portable-config-maven-plugin(不同环境打包)

    在大型的项目组中,分不同的开发环境,测试环境,生产环境(说白了就是配置文件不同,或者数据源,或者服务器,或者数据库等);问题来了,如何使用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其他的标签使用,不过以上内容总有相同之处--针对不同环境打包的一些解决方法


  • 相关阅读:
    IP地址和进制转换
    Cisco交换机常见配置
    macOS上的autoreconf错误导致无法安装问题
    LG P5147 随机数生成器
    LG P1879 [USACO06NOV]Corn Fields G
    LG P5017 [NOIP2018]摆渡车
    mysql触发器trigger详解
    MybatisPuls中QueryWrapper的select、update的用法
    @Transactional各属性详解
    Linux如何查看进程、杀死进程、启动进程等常用命令(包括常用的命令,如查看文件,修改文件读写权限、寻找文件等)
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3313247.html
Copyright © 2011-2022 走看看