maven lifecycle, phase and goal

當我們在使用Maven做一些工作,如打包,編譯,運行測試等等任務時,我們已經使用到了Maven中的幾個重要概念:

  • lifecycle
  • phase  
  • goal

例如,如果我們使用ant打包,我們需要清晰的在腳本中告訴ant 源代碼在哪,打包的目標文件類型如jar,目標文件夾在哪。首先要編譯,然後運行測試,最後打包。

而Maven爲了在最大程度上簡化我們的工作,因而定義了lifecycle, phase and goal。

我們僅僅需要簡單的運行 mvn package(package是一個phase), 包就自動打好了。

而實際上,mvn package這個命令會運行以下6個步驟(左邊這列是步驟名,同時也是phase的名字,右邊是對應的goal):

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

因此使用Maven打包時,用到的信息和步驟一點都不比用ant少,只不過使用到的信息,定義在了POM文件中(本文並不涉及), 而步驟定義在了lifecycle, phase and goal中。也就是說,Maven定義了一系列的best practice。

在這裏,對與打包這個任務,我們僅需要使用Maven中已經定義好的這些best practice,就能簡單的完成日常工作了。

下面我們首先介紹這些best practice,也就是定義好的lifecycle, phase, goal。

之後介紹如果我們不想使用best practice,比如,我們想在打包時,在上面的test-complie(這個步驟僅編譯測試代碼,但不會運行測試用例)之後,運行測試。同時,還希望能使用一個第三方工具檢查測試用例的代碼覆蓋率,並形成一個報表。也就是說,我們希望在打包結束時,同時得到一個測試代碼覆蓋率的報告,應該怎麼做。

預備知識

  • There are three built-in build lifecycles: default, clean and site.

有三種內置的build lifecycle:The default lifecycle handles your project deployment, the clean lifecycle handles project cleaning, while the site lifecycle handles the creation of your project’s site documentation.

  • Each of these build lifecycles is defined by a different list of build phases, wherein a build phase represents a stage in the lifecycle.
Lifecycle Phase Description
clean pre-clean  
clean  
post-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-classes  
test  
prepare-package  
package  
pre-integration-test  
integration-test  
post-integration-test  
verify  
install  
deploy  
site pre-site  
site  
post-site  
site-deploy  

這裏並不包含所有的phase,只是舉例):

  1. validate - validate the project is correct and all necessary information is available
  2. compile - compile the source code of the project
  3. test - test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
  4. package - take the compiled code and package it in its distributable format, such as a JAR.
  5. integration-test - process and deploy the package if necessary into an environment where integration tests can be run
  6. verify - run any checks to verify the package is valid and meets quality criteria
  7. install - install the package into the local repository, for use as a dependency in other projects locally
  8. deploy - done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.

執行一個phase將會執行這個lifecycle前面的所有phase。

best practice

下面這個例子執行了clean lifecycle和default lifecycle到install爲止的所有phase。 

mvn clean install
  • A Build Phase is made up of goals

However, even though a build phase is responsible for a specific step in the build lifecycle, the manner in which it carries out those responsibilities may vary.

And this is done by declaring the goals bound to those build phases.

A goal represents a specific task (finer than a build phase) which contributes to the building and managing of a project. 

也就是說,執行phase實際執行的是goal。如果一個phase沒有綁定goal,那這個phase就不會被執行。

一些phase默認已經綁定了一些goal。對於default lifecycle來說, 這些被綁定的goal並不完全相同,而是和packaging value相關。所謂的packaging value就是<packaging>jar</packaging>//這個很好理解,對於不同的包類型,打包的過程不盡相同,因此需要執行的goal也不同。

一個goal是獨立的,它可以被綁定到多個phase中去,也可以一個phase都沒有。如果一個goal沒有被綁定到任何一個lifecycle,它仍然可以直接被調用,而不是被lifecycle調用。

因此可以這樣理解phase與goal的關係:

  1. phase其實就是goal的容器。實際被執行的都是goal。phase被執行時,實際執行的都是被綁定到該phase的goal。
  2. goal與goal之間是獨立的。因此單獨執行一個goal不會導致其他goal被執行。

下面的例子

mvn clean dependency:copy-dependencies package

clean是phase。

dependency:copy-dependencies是plugin-in dependency 的goal copy-dependencies。

package也是一個phase。

maven會順序執行這3個對象中包含的所有goal。

custom practice - plugin

另外一種將goal綁定到phase的方法就是在project中使用plugin。即在POM中配置。

  • Plugins are artifacts that provide goals to Maven. Furthermore, a plugin may have one or more goals wherein each goal represents a capability of that plugin.

這裏我們先思考一個問題,goal的本質是什麼?

例如我們上面提到的需要,希望在打包時得到一個測試代碼覆蓋率的報告。

實現的方法就是:

1,將計算代碼覆蓋率的工具,例如cobertura,安裝到Maven的repository中。此時cobertura就是一個plugin。

最簡單的方法就是將cobertura加到項目的dependency中就行了。Maven會自動去網上的公共repository中下載項目依賴的的dependency到本地的repository中。

2,修改POM文件(可參考下面的pom的例子),將這個plugin,連同要執行的goal,加到package這個phase中去。

由於現在Maven已經非常流行,所以這些工具的官網上都會提供在Maven中使用該工具時,應使用什麼命令。

參考cobertura網站,我們可以知道對於這個工具,對應的命令是:

mvn cobertura:cobertura

(即phase和goal的名字都是cobertura)

3,此時再運行mvn package,就會運行cobertura這個plugin的goal,也就是cobertura。

之後我們就會在默認的位置找到生成的報表。

因此,goal其實是由存在於Maven的repository中的plugin提供的一個個小的功能程序。

它是Maven的lifecycle以及phase的基本組成元素。同時,我們也可以通過將各種各樣的goal加入到Maven的phase中,從而根據自己的實際需求,靈活實現各種定製功能。

下面是一個更general的例子,該POM中展示了,如何將display-maven-plugin中的goal time綁定到process-test-resources這個phase中。

 <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>

通過前面的例子我們明白,完全可以自行開發一個java程序,作爲goal綁定到phase中後執行。

但Maven對嵌入到它之中的plugin有一些標準,在開發程序時需要遵循。

下面鏈接中列出了主要的Maven plugin。

http://maven.apache.org/plugins/index.html

同時關於plugin還可以參考下面鏈接中的plugin文檔,得到更詳細的解釋。

http://maven.apache.org/guides/index.html

參考鏈接:

https://blog.csdn.net/u014241071/article/details/81668312

http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章