首先, 鄭重的吐槽下度娘, 能找到的資料, 都是說(shuō)針對(duì)打包
tar.gz
的, 找了好一會(huì)兒, 才找到針對(duì)war
包.
開(kāi)始并不順利, 因?yàn)樵诟缸幽K的場(chǎng)景下, 有war,有jar. 最后發(fā)現(xiàn)打包的lib里包含war包. 這樣不是重復(fù)打包嗎, 而且, 并不能打成標(biāo)準(zhǔn)war包結(jié)構(gòu).
好啦, 現(xiàn)在上正解.
工程結(jié)構(gòu):
parent //pom
| common //jar
| dao //jar
| web //war
針對(duì)中這種結(jié)構(gòu)的工程, 網(wǎng)上的tar.gz
的做法并不適用. 主要是: 1)會(huì)將web
模塊的war包打進(jìn)lib文件中; 2)目錄結(jié)構(gòu)不是war包應(yīng)有的結(jié)構(gòu). 前者是因?yàn)閙aven自帶的編譯打包工具會(huì)先執(zhí)行打包操作, 這樣輪到assembly打包時(shí)會(huì)將打好的war包打進(jìn)lib文件夾中.
針對(duì)上文的工程結(jié)構(gòu), 需要:
-
parent
pom中統(tǒng)一配置自帶的編譯插件. 主要是指定編譯的jdk版本.(否則默認(rèn)會(huì)使用1.5的. 不會(huì)的需要補(bǔ)充學(xué)習(xí)下). -
jar
模塊如果需要分環(huán)境打包配置文件, 則不需要任何多余的配置, 使用的默認(rèn)的jar打包即可. -
web
模塊是重點(diǎn). 下文的配置都是針對(duì)web的配置. 通常web工程更多的需要分環(huán)境打包配置文件.
web配置文件結(jié)構(gòu)
我這里的思路是: resources
下可以放置每個(gè)環(huán)境都需要的公共配置文件. 分環(huán)境的放在./src/main/assembly/
下.
1 web模塊的pom.xml中的profiles
配置
<profiles>
<!--profile1: 開(kāi)發(fā)環(huán)境 dev-->
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
<property>
<name>env</name>
<value>dev</value>
</property>
</activation>
<!--定制鍵值對(duì)環(huán)境變量
!重要: 這里才是將env=dev的變量傳入下面的assembly.xml中, 用于給${env}賦值, 上面的
<property>下面的那name,value并沒(méi)有什么亂用, 我也不知道別人為什么用這個(gè)!-->
<properties>
<env>dev</env>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<!-- maven assembly插件需要一個(gè)描述文件 來(lái)告訴插件包的結(jié)構(gòu)以及打包所需的文件來(lái)自哪里 -->
<descriptors>
<descriptor>${basedir}/src/main/assembly/assembly.xml</descriptor>
</descriptors>
<finalName>${project.artifactId}-${project.version}</finalName>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<!--profile2: 測(cè)試環(huán)境 test-->
<profile>
<id>test</id>
<activation>
<property>
<name>env</name>
<value>test</value>
</property>
</activation>
<properties>
<env>test</env>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<!-- 發(fā)布模式使用的maven assembly插件描述文件 -->
<descriptors>
<descriptor>${basedir}/src/main/assembly/assembly.xml</descriptor>
</descriptors>
<!-- 如果一個(gè)應(yīng)用的包含多個(gè)deploy模塊,如果使用同樣的包名棺牧, 如果把它們復(fù)制的一個(gè)目錄中可能會(huì)失敗巫糙,所以包名加了 artifactId以示區(qū)分 -->
<finalName>${project.artifactId}-${project.version}</finalName>
<!-- scm 要求 release 模式打出的包放到頂級(jí)目錄下的target子目錄中 -->
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<!--prod環(huán)境略-->
2 web模塊的pom.xml中引入assembly
插件
<build>
<plugins>
<!-- deploy模塊的packaging通常是jar,如果項(xiàng)目中沒(méi)有java 源代碼或資源文件颊乘,加上這一段配置使項(xiàng)目能通過(guò)構(gòu)建 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<archive>
<addMavenDescriptor>true</addMavenDescriptor>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<!-- 這是最新版本参淹,推薦使用這個(gè)版本 -->
<version>2.2.1</version>
<executions>
<execution>
<id>assemble</id>
<goals>
<goal>single</goal>
</goals>
<!--綁定package生命周期-->
<phase>package</phase>
</execution>
</executions>
<configuration>
<appendAssemblyId>false</appendAssemblyId> <!-- 設(shè)為 FALSE, 防止 WAR 包名加入 assembly.xml 中的 ID -->
<attach>false</attach>
</configuration>
</plugin>
</plugins>
</build>
3 配置定制assembly.xml
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>web</id>
<formats>
<format>war</format>
<!--生成同結(jié)構(gòu)的目錄, 方便查看, 可選-->
<format>dir</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<!--打war包的文件配置-->
<fileSets>
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<outputDirectory>WEB-INF/classes</outputDirectory>
</fileSet>
<!--分環(huán)境打包配置文件-->
<!-- ${env} 的值由 -P 的參數(shù)傳遞進(jìn)來(lái), 如:-Pdev, 那么, ${env} 的值就是 dev -->
<fileSet>
<directory>${project.basedir}/src/main/assembly/${env}</directory>
<outputDirectory>WEB-INF/classes</outputDirectory>
</fileSet>
<!--公共配置文件-->
<fileSet>
<directory>${project.basedir}/src/main/resources</directory>
<outputDirectory>WEB-INF/classes</outputDirectory>
</fileSet>
<!-- 將 webapp 下的文件輸出到 WAR 包 -->
<fileSet>
<directory>${project.basedir}/src/main/webapp</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
<dependencySets>
<!-- 將項(xiàng)目依賴的JAR包輸出到 WEB-INF/lib -->
<dependencySet>
<outputDirectory>WEB-INF/lib</outputDirectory>
<!--經(jīng)測(cè)試可以不需要-->
<!--<excludes>-->
<!--<exclude>*.war</exclude>-->
<!--</excludes>-->
<useProjectArtifact>false</useProjectArtifact>
</dependencySet>
</dependencySets>
</assembly>
這里采用的方案是, 不同環(huán)境公用同一個(gè)assembly.xm
l文件.
4 執(zhí)行打包的命令
各環(huán)境對(duì)應(yīng)的命令:
mvn clean package
mvn clean package -P dev
mvn clean package -P test
mvn clean package -P prod
后記
分環(huán)境打包的分支控制策略有兩種:
通過(guò)
profile
配置不同的環(huán)境下的配置, 然后打包的時(shí)候通過(guò)參數(shù)-P 環(huán)境id
定位到對(duì)應(yīng)profile
, 就會(huì)執(zhí)行該profile
下的所有配置, 包括自定義的properties
(這里的properties
和profile
外層的效果一樣). 本文采用的就是這個(gè)思路.
這種方案的好處是, 可以方便的定義默認(rèn)打包環(huán)境.不同環(huán)境的配置文件分別放在不同的路徑下, 打包配置中用
${env}
動(dòng)態(tài)執(zhí)行路徑, 然后打包時(shí)帶上參數(shù):-Denv=環(huán)境名稱
, 即動(dòng)態(tài)手動(dòng)指定環(huán)境名, 定位到對(duì)應(yīng)路徑下的配置文件. 這種方案看似簡(jiǎn)單好實(shí)施, 但有個(gè)缺陷就是不方便執(zhí)行默認(rèn)打包環(huán)境.
最后, 再次重復(fù)一個(gè)坑點(diǎn):
下圖中兩種property效果完全不同的, 上面的我完全不知道有什么鳥用, 下面的才是關(guān)鍵.