maven生命周期lifecycle和plugins介绍
一、Maven的生命周期
生命周期的定義:Maven的生命周期就是為了對所有的構建過程進行抽象和統一。在大量項目的構建過程中,Maven總結出了一套高度完善的,易于擴展的生命周期,包括項目的清理,初始化,編譯,測試,打包,集成測試,驗證,部署和生成站點等構建步驟。在我們日常的maven使用中,一條條簡單的命令,mvn clean, mvn package等都是在執行Maven的某個生命周期階段。Maven提供了三套獨立的生命周期:clean, default 和 site ,接下來我們分別介紹三套生命周期:
clean生命周期的目的是清理項目,刪除前一次構建在target文件夾下生成的各個Jar包等,它包含以下三個階段:
- pre-clean:執行一些清理前需要完成的工作
- clean:清理上一次構建生成的文件
- post-clean:執行一些清理后需要完成的工作
舉例:
我們在命令行中輸入: mvn clean 就是在調用clean生命周期的clean階段,實際執行了pre-clean和clean階段
default生命周期定義了真正構建項目中需要執行的所有步驟,它包含的階段如下:
validate
initialize
generate-sources
process-sources
generate-resources
process-resources
compile:編譯項目的主源碼
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources
test-compile
process-test-classed
test:使用單元測試框架運行測試,測試代碼不會被打包或部署
prepare-package
package:接受編譯好的代碼,打包成可發布的格式,jar/war等
pre-integration-test
integration-test
post-integration-test
verify
install
deploy
- 此處我們注意下 install 生命周期階段,若我們在當前的maven項目中執行 mvn install ,那么將執行validate到 install 的所有生命周期階段,結果就是將我們當前的項目打包并且安裝在了本地倉庫。但是install插件還有一個目標 install-file 該插件目標可以將我們普通Java項目到處的jar包安裝到本地倉庫。舉例如下:
-
mvn test 就是在調用default生命周期的test階段,實際執行了validate到test階段之間的所有階段
-
mvn clean package 就是在調用clean生命周期的clean階段和default生命周期的package階段,實際執行了pre-clean和clean階段和default生命周期validate到package階段之間的所有階段
-
mvn clean install 和 mvn clean deploy 所調用的生命周期階段請各位自行分析(對于聰明的你來說一定沒什么難度)
site生命周期的目的是建立和發布項目站點,Maven可以給予pom所包含的信息,生成一個站點,方便團隊交流和發布項目信息,其生命周期階段包含:
- pre- site
- site:生成項目站點文檔
- post-site
- site-deploy:將生成的項目站點發布到服務器上
二、plugins
好的,介紹了三套Maven生命周期之后,我們會有一個疑問:生命周期是抽象的,那么實際的任務如package,install等階段的任務都是怎么實現的呢?答案就是我們接下來要介紹的主角:插件(plugin)
生命周期的各個階段都是抽象的概念,真正干活的是一個個的插件,插件是以獨立的構件形式存在,我們將maven的生命周期的各個階段與maven的插件進行綁定,當我們執行mvn命令其實就是在指揮著一個個的插件在干活。
maven的插件以獨立的構件形式存在,為了能夠復用代碼,使得一個插件可以完成多個任務,我們定義了插件目標(Plugin Goal),每一個目標都可以完成不同的功能。
- maven-dependency-plugin插件具有多個功能,比如分析項目依賴,還能列出項目的依賴樹等。就是使用了analyze, tree和list等插件目標區分的。
- dependency : analyze
- dependency : tree
- denpendency : list
以上冒號左邊的表示插件前綴dependency,冒號右邊的表示插件的目標Goal
- 3.1內置綁定
maven的生命周期的各個階段與maven插件互相綁定,從而完成具體的構件任務。default生命周期的compile階段與maven-compiler-plugin插件的目標compile進行綁定的示意圖如下所示:
為了能夠讓用戶更加方便的構建項目,maven將大多數主要的生命周期階段都綁定了很多插件的目標。如下所示:
執行例子(以maven clean install為例)
由上圖可知,各個插件的執行順序一般是:1:clean、2:resources、3:compile、4:testResources、5:testCompile、6:test、7:jar、8:install。在圖中標記的地方每一行都是由冒號分隔的,前半部分是對應的插件,后半部分是插件的執行目標也就是插件執行產生的結果。現在我們來看下上面的pom文件,我們如配置了maven-compiler-plugin這個插件,其它的插件沒有配置,但最后項目構建成功,說明maven內置的各種插件,如果pom中沒有配置就調用默認的內置插件,如果pom中配置了就調用配置的插件。到此我們理解maven的構建過程或者有更多的人稱是打包,就是由各種插件按照一定的順序執行來完成項目的編譯,單元測試、打包、布署的完成。各種插件的執行過程也就構成的maven的生命周期(lifecycle)。生命周期(lifecycle)各個階段并非不能獨立的,可以單獨執行如mvn clean,也可以一起執行如mvn clean install。而且有的mvn命令其是包括多個階段的,如mvn compile其是包括了resources和compile兩個階段。下面分別來分析各個階段需要的插件和輸出的結果
- clean插件maven-clean-plugin
clean階段是獨立的一個階段,功能就是清除工程目前下的target目錄,對應的插件是 maven-clean-plugin,可以使用maven內置的插件,當然也可以自己在pom中配置。下面看下mvn執行前后工程目錄下的輸出對比
- resources插件maven-resources-plugin
resource插件的功能就是把項目需要的配置文件拷貝到指定的目錄,默認是拷貝src\main\resources目錄下的文件到classes目錄下,當然可以自己來配置源目錄和輸出目錄。resources插件一般不單獨執行,complie插件執行時會先調用resources插件。配置示例如下:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>x.x</version> <executions> <execution> <id>copy-resources</id> <!-- 在default生命周期的 validate階段就執行resources插件的copy-resources目標 --> <phase>validate</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <!-- 指定resources插件處理資源文件到哪個目錄下 --> <outputDirectory>${project.build.outputDirectory}</outputDirectory> <!-- 也可以用下面這樣的方式(指定相對url的方式指定outputDirectory) <outputDirectory>target/classes</outputDirectory> --> <!-- 待處理的資源定義 --> <resources> <resource> <!-- 指定resources插件處理哪個目錄下的資源文件 --> <directory>src/main/${deploy.env}/applicationContext.xml</directory> <!-- 指定不需要處理的資源 <excludes> <exclude>WEB-INF/*.*</exclude> </excludes> --> <!-- 是否對待處理的資源開啟過濾模式 (resources插件的copy-resources目標也有資源過濾的功能,這里配置的 這個功能的效果跟<build><resources><resource>下配置的資源過濾是一樣的,只不過可能執行的階段不一樣, 這里執行的階段是插件指定的validate階段,<build><resources><resource>下的配置將是在resources插件的resources目標執行時起作用(在process-resources階段)) --> <filtering>false</filtering> </resource> </resources> </configuration> <inherited></inherited> </execution> </executions> </plugin>- compile插件maven-compiler-plugin
compile插件執行時先調用resouces插件,功能就是把src\mainjava源碼編譯成字節碼生成class文件,并把編譯好的class文件輸出到target\classes目錄下。下面看執行結果:
- 單元測試所用插件
單元測試所用的compile和resources插件和主代碼是相同的,但執行的目標不同,目標testCompile和testResources是把src\test\java下的代碼編譯成字節碼輸出到target\test-classes,同時把src\test\resources下的配置文件拷貝到target\test-classes。看下面的輸出:
- 插件maven-surefire-plugin執行單元測試類的
在本例中就是運行contextLoads()方法,如果單元測試不通行,構建會失敗,在編譯正式的項目時可以使用mvn -Dmaven.test.skip=true 來跳過測試類的編譯和運行過程。mvn test可以單獨執行,但是這個命令其實是包括了resources、compile、testResources、testCompile、test這幾個階段,如下圖所示:
- 打包插件
這個插件是把class文件、配置文件打成一個jar(war或其它格式)包。依賴包是不在jar里面的,需要建立lib目錄,且jar和lib目錄在同級目錄。常用的打包插件有maven-jar-plugin、maven-assembly-plugin、maven-shade-plugin三種,下面分別介紹下各自己pom配置和使用特點。
- maven-jar-plugin
可執行jar與依賴包是分開,需建立lib目錄里來存放需要的j依賴包,且需要jar和lib目錄在同級目錄
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>2.6</version><configuration><archive><manifest><addClasspath>true</addClasspath><classpathPrefix>lib/</classpathPrefix><mainClass>com.xxx.xxxService</mainClass></manifest></archive></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><version>x.x</version><executions><execution><id>copy-dependencies</id><phase>package</phase><goals><goal>copy-dependencies</goal></goals><configuration><outputDirectory>${project.build.directory}/lib</outputDirectory></configuration></execution></executions></plugin>- maven-assembly-plugin
這個插件可以把所有的依賴包打入到可執行jar包。但是該插件有個bug會缺失spring的xds文件,導致無法運行jar,同時如果同級目錄還有其它可執行jar文件依賴可能會產生沖突。
<plugin><artifactId>maven-assembly-plugin</artifactId><configuration><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs><archive><manifest><mainClass>com.xxx.xxxService</mainClass></manifest></archive></configuration><executions><execution><id>make-assembly</id><phase>package</phase><goals><goal>single</goal></goals></execution></executions></plugin>- maven-shade-plugin
所有的依賴包打入到可執行jar包,如果同級目錄有其它可執行jar,依賴可能會產生沖突,且運行jar時,有時會出現SF、DSA、RSA文件沖突的提示,需要排除META-INF目錄下的文件。
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>x.x.x</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><filters><filter><artifact>*:*</artifact><excludes><exclude>META-INF/*.SF</exclude><exclude>META-INF/*.DSA</exclude><exclude>META-INF/*.RSA</exclude></excludes></filter></filters><transformers><transformerimplementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>META-INF/spring.handlers</resource></transformer><transformerimplementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>META-INF/spring.schemas</resource></transformer><transformerimplementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>META-INF/spring.tooling</resource></transformer><transformerimplementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>com.xxx.xxxInvoke</mainClass></transformer></transformers><minimizeJar>true</minimizeJar><shadedArtifactAttached>true</shadedArtifactAttached></configuration></execution></executions></plugin>- 發布插件maven-install-plugin
發布插件的功能就是把構建好的artifact部署到本地倉庫,還有一個deploy插件是將構建好的artifact部署到遠程倉庫。
- 3.2 自定義綁定
前面說了maven的內置綁定,當然maven為了滿足用戶多元化的構建過程,是允許我們自定義的選擇將某個插件綁定到生命周期的某個階段的。接下來,我們將maven-source-plugin插件的jar-no-fork任務綁定到verify生命周期階段,我們只需要在pom中增加如下的配置即可:
執行:mvn verify
可以看到我們剛剛自定義的綁定插件maven-source-plugin的目標jar-no-fork被執行,并且在項目的構建輸出的/target/下出現了-source包。
三、插件的配置
在項目的配置文件pom中,我們可以對插件進行一個全局的配置,,我們可以在中配置來搞定,舉例如下:
<plugins> <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.4</version><configuration><source>1.6</source><target>1.6</target><fork>true</fork><verbose>true</verbose><encoding>UTF-8</encoding><compilerArguments><sourcepath>${project.basedir}/src/main/java</sourcepath></compilerArguments><compilerArgument>-XDignore.symbol.file</compilerArgument></configuration></plugin></plugins>該配置表示我們要編譯Java1.6版本的源文件,生成與JVM1.6兼容的字節碼文件。
四、總結
本文闡述了maven中的兩個重要概念生命周期和插件。正是生命周期階段和插件的互相綁定,我們才能真正完成項目的構建。常用的插件如下:有需要深入了解的可以自行查閱相關資料。
-
maven-assembly-plugin :自定義打包方式,還是很有趣的,感興趣的可以研究哦
-
maven-enforcer-plugin :展示項目依賴沖突
-
maven-antrun-plugin :運行ant腳本
-
maven-dependency-plugin :分析項目依賴
-
maven-clean-plugin :清理
-
maven-compiler-plugin :編譯
-
maven-source-plugin :源碼
-
maven-war-plugin :打包
-
maven-jar-plugin:打包
-
maven-surefire-plugin :測試
-
maven-resources-plugin :資源文件處理
文章轉自
文章轉自
總結
以上是生活随笔為你收集整理的maven生命周期lifecycle和plugins介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: windows 包管理器scoop的使用
- 下一篇: 2020中国信息流平台品牌服务价值分析