1. 程式人生 > >Maven中的幾個重要概念(二):lifecycle, phase and goal

Maven中的幾個重要概念(二):lifecycle, phase and goal

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

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

lifecycle, phase and 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 thesite 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.

For example, the default lifecycle has the following build phases (這裡並不包含所有的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。

下面這個例子執行了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的關係:

phase其實就是goal的容器。實際被執行的都是goal。phase被執行時,實際執行的都是被繫結到該phase的goal。

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。

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