【乾貨】常用maven外掛總結

天府雲創發表於2017-03-28

maven是目前java專案中比較流行的構建工具,特別是它提供的外掛,如果使用得當,整個專案研發流程都將會受益,從而提高研發、測試和部署的效率。這裡記錄幾個常用外掛的用法,既方便自己日後回顧,也便於有興趣的同仁交流指正。各位實踐過程中如果發現有趣的外掛或者更好的用法,也歡迎留言分享。

Maven工程標準架構 

目錄 備註
${basedir} 存放 pom.xml和所有的子目錄
${basedir}/src/main/resources 專案的資源,如spring配置檔案,properties資原始檔等
${basedir}/src/main/webapps web專案特有
${basedir}/src/test/java 專案的測試類,比如說 JUnit程式碼、TestNg程式碼
${basedir}/src/test/resources 測試程式碼使用的資源

外掛一 maven-resources-plugin

Maven可以區別對待Java程式碼檔案和資原始檔,預設的主資原始檔目錄是src/main/resources,我們可以通過這個外掛實現資原始檔過濾。資原始檔過濾的意思是指我們可以在資原始檔裡用使用佔位符${propertyName},然後開啟對資原始檔的過濾,pom.xml裡再統一設定所有{propertyName}對應的值,就可以在構建過程中將值替換掉資原始檔中對應的${propertyName},實現了程式碼配置分離、做到了引數的統一維護。

示例用法

<resources>
    
<resource>
        
<directory>src/main/resources</directory>
        
<includes>
            
<include>properties/*.properties</include>
        
</includes>
        
<filtering>true</filtering>
    
</resource>
    
<resource>
        
<directory>src/main/resources</directory>
        
<includes>
            
<include>*.xml</include>
            
<include>mapper/**/*.xml</include>
            
<include>mysqlMapper/**/*.xml</include>
            
<include>*.properties</include>
        
</includes>
    
</resource>
</resources>
……
<
properties>
    
<runtime.env>local</runtime.env>
</
properties>

我們的主應用整合後,會根據實際要求部署到不同的環境中,比如聯調環境、測試環境、壓力環境、預釋出環境、生產環境等,而這些環境上的資源配置資訊顯然是不一樣的,針對每套環境,每個具體佔位符${propertyName}都會有不同的值,而這種場景可以使用Maven的profile來支援,每個profile都可以獨立維護一套引數值,在mvn package的時候靈活指定;此外,maven也支援在package的時候指定多個profile,這個特性在執行自動部署的時候特別有用。使用這個外掛,我們的專案可以做到多環境支援,參考命令

mvn package -Pnocheck,env-test 

示例用法

<profiles>
    
<profile>
        
<id>nocheck</id>
        
<properties>
            
<skipTests>true</skipTests>
            
<checkstyle.skip>true</checkstyle.skip>
            
<license.skip>true</license.skip>
            
<notice.skip>true</notice.skip>
            
<versions.skip>true</versions.skip>
        
</properties>
    
</profile>
    
<profile>
        <!-- 本地環境,預設是windows -->
        
<id>local</id>
        
<activation>
            
<activeByDefault>true</activeByDefault>
        
</activation>
        
<properties>
            
<runtime.env>local</runtime.env>
        
</properties>
    
</profile>
    
<profile>
        
<id>env-test</id>
        
<properties>
            
<runtime.env>env-test</runtime.env>
        
</properties>
    
</profile>
</
profiles>

外掛二 maven-jar-plugin

當我們將專案模組化後,有一些通用的資原始檔基本上大多數模組都會用到,比如log4j.properties,jdbc.properties等,模組中有了這些資原始檔,我們才能單獨對該模組進行開發、除錯。預設情況下maven-jar-plugin會將這些資原始檔全部package成一個jar包進行釋出,如果這樣的jar包整合到一個主應用中部署,執行,很可能導致主應用的配置不生效,我稱之為配置混亂,為了解決這個問題,可以開啟maven-jar-plugin的排除功能,在執行mvn package之前排除指定的資原始檔。

示例用法

<plugin>
    
<groupId>org.apache.maven.plugins</groupId>
    
<artifactId>maven-jar-plugin</artifactId>
    
<configuration>
        
<excludes>
            
<exclude>applicationContext.xml</exclude>
            
<exclude>properties/**</exclude>
            
<exclude>log4j.properties</exclude>
        
</excludes>
    
</configuration>
</
plugin>

外掛三 maven-war-plugin

專案如果是web主應用,我們可以使用maven-war-plugin來對webapps下各類檔案進行過濾。用法參考maven-resources-plugin

示例用法

<plugin>
    
<groupId>org.apache.maven.plugins</groupId>
    
<artifactId>maven-war-plugin</artifactId>
    
<configuration>
        
<warName>demo-Rest</warName>
        
<webResources>
            
<resource>
                
<directory>src/main/webapp/WEB-INF</directory>
                
<filtering>true</filtering>
                
<targetPath>WEB-INF</targetPath>
                
<includes>
                    
<include>web.xml</include>
                
</includes>
            
</resource>
        
</webResources>
    
</configuration>
</
plugin>


外掛四 properties-maven-plugin

隨著專案的不斷迭代,我們的資源配置項將會變得更多,這個會直接影響到pom.xml的體積膨脹;此外,如果專案目標部署環境比較多,pom.xml將會膨脹得更快,更加難以維護。為了解決這個問題,我們需要將這些配置資訊獨立出來,並按照不同環境進行歸類,使用properties-maven-plugin就會達到這個效果。 

示例用法(將每個環境的資訊放在不同的目錄下,然後在mvn package切換不同的profile實現去指定目錄讀取配置資訊,用讀取到的value去替換資源配置檔案的佔位符)

<plugin>
    
<groupId>org.codehaus.mojo</groupId>
    
<artifactId>properties-maven-plugin</artifactId>
    
<version>1.0.0</version>
    
<configuration>
        
<files>
            
<file>profiles/${runtime.env}/jdbc.properties</file>
            
<file>profiles/${runtime.env}/redis.properties</file>
            
<file>profiles/${runtime.env}/batch.properties</file>
            
<file>profiles/${runtime.env}/config.properties</file>
        
</files>
    
</configuration>
    
<executions>
        
<execution>
            
<phase>initialize</phase>
            
<goals>
                
<goal>read-project-properties</goal>
            
</goals>
        
</execution>
    
</executions>
</
plugin>


外掛五 maven-assembly-plugin

Java專案中有一種型別的主應用,是需要獨立部署在後臺啟動的,比如socket服務程式,比如定時排程程式,比如dubbo服務程式,這些程式理論上只需要執行一個簡單的java命令即可;稍微複雜一些的,我們可以規範一下自己的主應用結構,定義配置資料夾和依賴庫資料夾,再準備啟動的批處理指令碼sh或bat檔案即可。使用maven-assembly-plugin就可以達到這種效果。

示例用法 

<plugin>
    
<groupId>org.apache.maven.plugins</groupId>
    
<artifactId>maven-assembly-plugin</artifactId>
    
<configuration>
        
<appendAssemblyId>false</appendAssemblyId>
        
<descriptors>
            
<descriptor>target/classes/package.xml</descriptor>
        
</descriptors>
    
</configuration>
    
<executions>
        
<execution>
            
<id>make-assembly</id>
            
<phase>package</phase>
            
<goals>
                
<goal>single</goal>
            
</goals>
        
</execution>
    
</executions>
</
plugin>

附package.xml

<assembly
xmlns
="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    
<id>package</id>
    
<formats>
        
<format>tar.gz</format>
    
</formats>
    
<includeBaseDirectory>true</includeBaseDirectory>
    
<fileSets>
        
<fileSet>
            
<directory>src/main/bin</directory>
            
<includes>
                
<include>*.sh</include>
                
<include>*.bat</include>
            
</includes>
            
<filtered>true</filtered>
            
<outputDirectory></outputDirectory>
            
<fileMode>0755</fileMode>
        
</fileSet>
        
<fileSet>
            
<directory>${basedir}/src/main/config</directory>
            
<includes>
                
<include>*.properties</include>
                
<include>log4j.xml</include>
            
</includes>
            
<outputDirectory>config</outputDirectory>
            
<filtered>true</filtered>
            
<fileMode>0644</fileMode>
        
</fileSet>
        
<fileSet>
            
<directory>${basedir}/src/main/config</directory>
            
<includes>
                
<include>log4j.dtd</include>
            
</includes>
            
<outputDirectory>config</outputDirectory>
            
<fileMode>0644</fileMode>
        
</fileSet>
    
</fileSets>
    
<dependencySets>
        
<dependencySet>
            
<outputDirectory>lib</outputDirectory>
            
<scope>runtime</scope>
            
<fileMode>0644</fileMode>
        
</dependencySet>
    
</dependencySets>
</
assembly>

附示例生成的Java應用結構圖

外掛六 maven-shade-plugin

有時候,我們需要將所有配置檔案和依賴庫檔案全部放在一個jar包中,運維的同事只需要執行java -jar batch.jar即可完成啟動。雖然使用maven-assembly-plugin也可以做到這一點,但是在讀取配置檔案的時候有可能會遇到一些問題,這個時候,我們可能需要使用到maven-shade-plugin這個外掛,經筆者實踐按照如下示例用法配置確實可用;當然本示例配置了mainClass,直接執行java -jar batch.jar確實沒問題,但如果執行java com.fastjrun.demospring4.BatchInit -classpath batch.jar也是可以的。

示例用法 

<plugin>
    
<groupId>org.apache.maven.plugins</groupId>
    
<artifactId>maven-shade-plugin</artifactId>
    
<version>3.0.0</version>
    
<executions>
        
<execution>
            
<phase>package</phase>
            
<goals>
                
<goal>shade</goal>
            
</goals>
            
<configuration>
                
<finalName>batch</finalName>
                
<shadedArtifactAttached>true</shadedArtifactAttached>
                
<shadedClassifierName>jar-with-dependencies</shadedClassifierName>
                
<transformers>
                    
<transformer
                        
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        
<mainClass>com.fastjrun.demospring4.BatchInit</mainClass>                    </transformer>
                    
<transformer
                        
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        
<resource>META-INF/spring.handlers</resource>
                    
</transformer>
                    
<transformer
                        
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        
<resource>META-INF/spring.schemas</resource>
                    
</transformer>
                    
<transformer
                        
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        
<resource>META-INF/spring.tooling</resource>
                    
</transformer>
                
</transformers>
                
<filters>
                    
<filter>
                        
<artifact>*:*</artifact>
                        
<excludes>
                            
<exclude>META-INF/*.SF</exclude>
                            
<exclude>META-INF/*.DSA</exclude>
                            
<exclude>META-INF/*.RSA</exclude>
                        
</excludes>
                    
</filter>
                
</filters>
            
</configuration>
        
</execution>
    
</executions>
</
plugin>

外掛七 versions-maven-plugin

當專案模組化後,我們會遇到一個問題,就是專案版本升級的時候,需要同時變更父模組和所有子模組中的版本號 ,而這是一個比較瑣碎且容易出錯的事情,還好maven考慮得很周到,提供了這樣一個外掛,我們使用命令列就可以達到效果了。我們的專案檢視如下

參考命令如下

mvn versions:set -DnewVersion=1.2-SNAPSHOT

總結

本文彙總了筆者常用的幾個外掛及其用法,經實踐,基於eclipse的kepler、luna版本都能很好支援maven-resources-plugin、maven-jar-plugin、maven-war-plugin和properties-maven-plugin使用,同時也支援profile的activeByDefault設定,研發同事在不需要任何調整的情況下就能直接開發、除錯程式碼,且在開發結束後,可以直接使用mvn命令打包,打出各個環境的部署程式。從開發、除錯、測試、驗證到上線的整個過程,所有模組的pom.xml直到下一個迭代變更版本前都不用修改,直接使用。

相關文章