1. 程式人生 > >《Mavan官方文件》構建生命週期介紹

《Mavan官方文件》構建生命週期介紹

構建生命週期基礎

Maven是以構建生命週期這個核心概念為基礎。構建生命週期是指為一個工程進行專案構建和分發的過程。

為了構建一個工程,有必要去學習一系列構建Maven專案的命令,並且POM檔案會確保他們能夠得到想要的結果。

Maven中內建了三個構建生命週期:default,clean和site。default生命週期處理工程的部署,clean生命週期處理工程的清理,而site生命週期則負責建立工程的站點文件。

構建生命週期是由階段組成的

三個構建生命週期都是由一系列不同的構建階段組成,每一個構建階段代表了生命週期的一個階段。

例如:default生命週期是由以下的階段組成(檢視完整的生命週期階段列表,請參考

生命週期參考):

  • validate – 驗證該專案是否正確,所有必要的資訊都是可用的
  • compile – 編譯工程原始碼
  • test – 使用一個合適的單元測試框架測試編譯的原始碼。這些測試的程式碼不會被打包或部署到專案中
  • package – 將編譯的程式碼打包成它釋出的格式,例如JAR
  • integration-test – 如果必要的話,該命令會將工程處理並部署在一個整合測試執行的環境中
  • verify – 執行任何檢查以驗證該包是否有效,是否符合質量標準
  • install – 將工程打包安裝到本地倉庫中,以便本地其他專案可以進行依賴
  • deploy – 在整合或釋出環境中,將最終工程打包複製到遠端倉庫中,用於與其他開發人員和專案共享

這些生命週期階段(包括那些這裡沒有展示的其他生命週期階段)會順序地執行來完成預設的生命週期。上述的生命週期階段,意味著當你使用預設的生命週期時,Maven將首先驗證專案,然後將編譯原始碼,執行那些單元測試,再打包二進位制檔案(例如:jar),然後再對包檔案進行整合測試,再校驗包檔案,並將已經校驗的包檔案安裝到本地倉庫,然後在指定的環境中部署包。
要做到所有這些,你只需要呼叫最後一個生命階段來執行,在這種情況下進行部署:

mvn deploy

這是因為如果你呼叫了一個生命階段,它不僅執行指定的構建階段,而且會執行指定構建階段之前的每一個階段。因此,執行

mvn integration-test

將會先執行該階段之前的每一個階段(validate, compile, package等)。
生命週期中包含了許多命令,這些將要在接下來的部分進行討論。
需要指出的是同樣的命令可以用在多模組的情況下(即包含一個或多個子專案的工程)。例如:

mvn clean install

這個命令將會遍歷所有的子專案,並且執行clean命令,然後執行install命令(包含所有之前步驟的命令)

構建階段是由外掛目標組成的

即便構建階段在生命週期中是一個特定的步驟,但是它實現這些功能的方式也可能會有所不同。這些功能是通過宣告外掛目標並且繫結到具體的構建階段來實現的。
一個外掛目標代表了一個特定的任務(比構建階段更加貼切),這個任務有助於專案的建立和管理。它可能被繫結到零個或多個構建階段。一個目標沒有被繫結到任何構建階段,可以通過直接呼叫來執行這個構建生命週期以外的目標。執行的順序取決於目標和構建階段的順序。例如以下的這個命令:clean和package的引數是構建階段,而dependency:copy-dependencies是一個外掛目標。

mvn clean dependency:copy-dependencies package

如果這個命令被執行,clean階段將首先執行(這意味著它將執行所有的clean生命週期前的階段,包括clean階段自身),然後在執行package階段之前(及其前建立預設的生命週期階段),將執行dependency:copy-dependencies目標。
如果一個目標被繫結到一個或多個構建階段,這個目標將會被這些階段所呼叫。
此外,構建階段也可以繫結零個或更多的目標。如果構建階段沒有繫結目標,則該構建階段將不執行。但如果它有一個或多個目標,它將執行所有這些繫結的目標(注:在Maven2.0.5及以上版本,多目標繫結到一個階段是按照POM檔案中定義的順序進行執行,但是相同外掛不支援多個例項。在Maven2.0.11及以上版本,相同外掛的多個例項被劃分成一個組,統一併有序地執行)。

使用構建生命週期來設定專案

構建生命週期的使用足夠簡單,但是當你為一個專案進行Maven構建時,你如何分配每個構建階段的任務呢?

第一,也是最常見的方式,就是通過相同名稱的POM元素來為你的專案設定包。一些有效的包的值如下:jar,war, ear和pom。如果沒有指定包的值,它將預設為jar包。
每一次打包都包含一系列綁定了特殊階段的目標。例如,打jar包將繫結以下目標,來構建預設生命週期中的各個階段。

process-resources resources:resources
compile compiler:compile
process-test-resources resources:testResources
test-compile compiler:testCompile
test surefire:test
package jar:jar
install install:install
deploy deploy:deploy

這是一個幾乎標準的繫結設定;然而,一些包的處理方式有所不同。例如,一個專案,是純粹的元資料(包的值是POM),它僅僅綁定了install和deploy階段(獲取一個完整的打包型別的目標構建清單,請參考生命週期參考)。
值得注意的是,一些包型別即便可用,您可能還需要在你的POM檔案中的build部分引入一個特殊的外掛並且為那個外掛定義true。舉個例子,每個外掛都需要引入Plexus這個外掛,它提供了plexus-application和plexus-service包。

外掛

向構建階段加入目標的第二種方式是在你的專案中配置外掛。外掛就是向Maven提供目標的構建。此外,一個外掛可能會有一個至多個的目標,外掛中的每一個目標都代表了外掛的一個功能。例如:編譯外掛擁有兩個目標:compile和testCompile目標。前者會編譯你的功能程式碼,而後者則會編譯測試程式碼。
正如你將要在後面部分看到的那樣,外掛會包含一些顯示目標具體繫結到哪個生命週期階段的資訊。注意,只新增一個外掛自身的資訊是不夠的,你必須同時定義你想要執行的目標來做為你外掛的一部分。
已經配置的目標將會被新增到已經綁定了包的生命週期的目標上去。如果有超過一個目標繫結到一個特殊的階段,包中配置的目標將會被優先執行,然後再執行POM中配置的目標。注意,你可以使用元素來控制特殊目標的順序。
例如,Modello外掛預設將它的目標modello:java繫結到了generate-sources階段(注:modello:java目標用於生成java原始碼)。所以當使用Modello外掛並想讓它整合到一個構建階段中來生成一個模組的程式碼時,你需要將下列程式碼新增到你POM檔案元素下的中:

...
 <plugin>
   <groupId>org.codehaus.modello</groupId>
   <artifactId>modello-maven-plugin</artifactId>
   <version>1.8.1</version>
   <executions>
     <execution>
       <configuration>
         <models>
           <model>src/main/mdo/maven.mdo</model>
         </models>
         <version>4.0.0</version>
       </configuration>
       <goals>
         <goal>java</goal>
       </goals>
     </execution>
   </executions>
 </plugin>
...

你也許會疑惑為什麼元素會放在這。那是為了讓你能夠在需要時多次執行不同配置的同一目標。也可以通過設定一個ID來實現單獨執行,以便於不管是目標配置被分割還是進入一個額外的排除,你都能夠控制繼承或者應用程式的配置。
當設定的多個排除匹配同一個特殊階段時,他們按照POM檔案中定義的順序執行,繼承的排除設定優先執行。
現在,在modello:java這種情況下,它僅僅在generate-sources階段起作用。但是許多目標能夠在多個階段中使用,而且他們沒有一個明確的預設值。對於這些,你可以自定義階段。比如說,你有一個目標display:time,它能夠將當前的時間回顯在命令列中,你想在開始測試時,讓它在process-test-resources階段執行,去顯示當前時間。這就應該像這樣配置:

...
 <plugin>
   <groupId>com.mycompany.example</groupId>
   <artifactId>display-maven-plugin</artifactId>
   <version>1.0</version>
   <executions>
     <execution>
       <phase>process-test-resources</phase>
       <goals>
         <goal>time</goal>
       </goals>
     </execution>
   </executions>
 </plugin>
...

生命週期參考

下面的列表就是default,clean和site生命週期中的所有構建階段,他們將會按照他們定義的順序去執行。
Clean生命週期

pre-clean 執行一些清理前需要完成的工作
clean 清理上一次構建生成的檔案
post-clean 執行一些清理後需要完成的工作

Default生命週期

validate 校驗專案是否正確以及所有重要資訊是否可用
initialize 初始化構建狀態,例如:設定屬性或者建立目錄
generate-sources 生成編譯中包含的原始碼
process-sources 處理專案資原始檔,例如過濾一些值
generate-resources 生成包中包含的資源
process-resources 複製並處理資源到目標目錄,準備打包
compile 編譯專案中的原始碼
process-classes 後處理編譯生成的檔案,例如:對class檔案進行位元組碼增強
generate-test-sources 生成編譯中包含的測試原始碼
process-test-sources 處理測試原始碼,例如:過濾一些值
generate-test-resources 建立測試用的資原始檔
process-test-resources 複製並處理資源到目標測試目錄
test-compile 編譯測試原始碼放入測試目標資料夾中
process-test-classes 後處理測試編譯生成的檔案,例如:對class檔案進行位元組碼增強,對Maven 2.0.5及以上有效
test 使用單元測試框架執行測試。測試程式碼不會被打包或者部署。
prepare-package 執行必要的操作,在真正打包前準備一個包。這通常會產生一個未打包、處理過版本。(Maven 2.1及以上)
package 接受編譯好的程式碼,打包成可釋出的格式,如:JAR
pre-integration-test 在整合測試執行前進行些必要的操作。這也許會涉及相關的東西,例如安裝必須的環境。
integration-test 處理並將包檔案部署到繼承測試執行的環境
post-integration-test 繼承測試執行之後進行的必要操作。這可能包含了清理環境操作。
verify 執行一些校驗去驗證包是否有效,是否符合質量標準。
install 安裝包到本地倉庫,供本地其他專案依賴使用
deploy 將最終的包複製到遠端倉庫,供其他開發人員和Maven專案使用

Site生命週期

pre-site 執行一些在生成站點之前需要完成的工作
site 生成專案的站點文件
post-site 執行一些在生成站點之後需要完成的工作
site-deploy 將生成的站點檔案釋出到遠端伺服器上

<h1>內建的生命週期繫結</h1>

許多階段都預設綁定了一些目標。對預設生命週期來說,這些繫結依賴包的值,一下就是一些目標和構建階段的繫結。

Clean生命週期繫結

clean clean:clean

Default生命週期繫結 – 包 ejb / ejb3 / jar / par / rar / war

process-resources resources:resources
compile compiler:compile
process-test-resources resources:testResources
test-compile compiler:testCompile
test surefire:test
package ejb:ejb or ejb3:ejb3 or jar:jar or par:par or rar:rar or war:war
install install:install
deploy deploy:deploy

Default生命週期繫結 – 包 ear

generate-resources ear:generate-application-xml
process-resources resources:resources
package ear:ear
install install:install
deploy deploy:deploy

Default生命週期繫結 – 包 maven-plugin

generate-resources plugin:descriptor
process-resources resources:resources
compile compiler:compile
process-test-resources resources:testResources
test-compile compiler:testCompile
test surefire:test
package jar:jar and plugin:addPluginArtifactMetadata
install install:install
deploy deploy:deploy

Default生命週期繫結 – 包 pom

package site:attach-descriptor
install install:install
deploy deploy:deploy

Site生命週期繫結

site site:site
site-deploy site:deploy

參考

全部的Maven生命週期是由maven-core模組的components.xml檔案定義的,可以參考associated documentation

在Maven 2.x中,預設生命週期繫結被包含在components.xml中,但在Maven 3.x中,他們被單獨定義在default-bindings.xml描述檔案中。