《Maven實戰》閱讀總結(三)Maven生命週期與插件

Maven生命週期與插件

除了座標、依賴以及倉庫以外,Maven另外兩個核心概念是生命週期和插件。命令行的輸入每每對應生命週期,而生命週期是抽象的,實際行爲由插件完成。html

何爲生命週期

在Maven出現以前,項目構建的生命週期就已經存在,清理、編譯、測試及部署。但公司與公司間,項目與項目間,每每使用不一樣方式作相似的工做。
Maven的生命週期對全部的構建過程進行抽象和統一。這個生命週期包括項目的清理、初始化、編譯、測試、打包、集成測試、驗證、部署和站點生成等幾乎全部構建步驟。
Maven的生命週期是抽象的,實際任務都交由插件來完成。這種思想與設計模式中的模板方法(Template Method)很是類似,生命週期是模板方法,而插件就是子類覆寫的方法。apache

總結:Maven的生命週期定義了項目構建的流程,而插件負責實現流程中每一個步驟,最後將插件與生命週期流程中每一個步驟綁定便可完成項目構建。在這個過程當中插件能夠在多個項目中複用,而經過更換插件綁定亦可實現差別化構建。設計模式

生命週期詳解

Maven擁有三套相互獨立的生命週期。服務器

生命週期 階段(phase) 說明
clean pre-clean 執行清理前須要完成的工做
clean 清理上一次構建生成的文件
post-clean 執行清理後須要完成的工做
default vaildate 驗證,確保當前配置和POM內容是有效的,包含對POM文件樹的驗證。
intianlize 初始化,執行構建生命週期的主任務以前的初始化
generate-sources 生成源碼,代碼生成器生成後期階段中處理或編譯的源代碼
proccess-sources 處理源碼,提供解析、修改和轉換源碼。常規源碼和生成的源碼均可以再這裏處理
generate-resoureces 生成資源,生成非源碼資源,一般包括元數據文件和配置文件
process-resources 處理資源,處理非源碼資源,修改、轉換和重定位資源都能在這階段發生
compile 編譯,編譯源碼。編譯過的類被放到目標目錄樹中
process-classes 處理類,處理類文件轉換和加強步驟。字節碼交織器和經常使用工具常在這一階段操做
generate-test-sources 生成測試源碼,生成要操做的單元測試代碼
process-test-sources 處理測試源碼,在編譯前對測試源碼執行任何須要的處理。修改、轉換或複製源代碼
generate-test-resources 生成測試資源,生成與測試相關的非源碼資源
process-test-resources 處理測試資源,處理、轉換或從新定位於測試相關的資源
test-compile 測試編譯,編譯單元測試的源碼
process-test-classes 處理測試類,對編譯生成文件作後期處理(Maven2.0.5及以上)
test 測試,運行編譯過的單元測試並累計結果
prepare-package 執行打包前的全部操做(Maven2.1及以上)
package 打包,將可執行的二進制文件打包到一個分佈式歸檔文件中,如jar或war
pre-integration-test 前集成測試,準備集成測試,將歸檔文件部署到一個服務器上執行
integration-test 集成測試,執行真正的集成測試,指在一個受到必定控制的模擬的真實部署環境中測試代碼
post-integration-test 後集成測試,解除集成測試準備,涉及環境重置或從新初始化
verify 檢驗,檢驗可部署歸檔文件的有效性和完整性,經過後,將安裝該歸檔
install 安裝,將項目包安裝到本地倉庫,供其餘項目依賴
deploy 部署,將項目發佈到遠程倉庫,供其餘開發人員與項目共享
site pre-site 執行一些在生成項目站點以前須要完成的工做
site 生成項目站點文檔
peo-site 執行一些在生成項目站點以後須要完成的工做
site-deploy 將生成的項目站點發布到服務器上

生命週期詳解

從命令行執行Maven任務的最主要方式就是調用Maven的生命週期階段。
Ps:Maven的三套生命週期是相互獨立的,而一個生命週期階段是有先後依賴關係的。
如:
mvn clean:該命令調用clean生命週期的clean階段,實際執行clean生命週期中的pre-clean,clean階段
mvn test:該命令調用default生命週期的test階段,實際執行default生命週期中vaildate至test全部階段
mvn clean install:該命令調用clean生命週期的clean階段以及default生命週期的install階段,實際執行clean生命週期中的pre-clean,clean階段,以及default生命週期的vaildate至install全部階段。
mvn clean deploy site-deploy:該命令調用clean生命週期的clean階段、default生命週期的deploy階段以及site生命週期的site-deploy階段,實際執行實際執行clean生命週期中的pre-clean,clean階段、default生命週期的全部階段以及site生命週期的全部階段。
因爲Maven中主要生命週期階段很少,而經常使用Maven命令都是基於這些階段簡單組合而成,所以只要對Maven生命週期有基本的理解,就能夠正確而熟練地使用Maven命令maven

插件目標

Maven的核心僅定義了抽象的生命週期,具體的任務是交由插件完成,插件以獨立的構件形式存在。
對於插件自己,爲了代碼複用,它每每具有多個功能,而每一個功能都統稱爲插件目標(Plugin Goal)。
如:maven-dependency-plugin,基於項目依賴作不少事情。
1 幫助分析項目依賴,幫助找出潛在的無用依賴;
2 列出項目依賴樹,幫助分析依賴來源
3 列出項目已解析的依賴 等...
這些任務有不少代碼能夠複用。所以,這些功能彙集在一個插件中,每一個功能就是一個插件目標。
插件目標使用語法:
1 完整命令 mvn groupId:artifactId:version:goal 如 mvn org.apache.maven.plugins:maven-dependency-plugin:3.0.2:tree
2 簡化version mvn groupId:artifactId:goal 如 mvn org.apache.maven.plugins:maven-dependency-plugin:tree
3 使用插件前綴 mvn 插件前綴:goal 如 mvn dependency:tree分佈式

插件綁定

Maven的生命週期與插件目標相互綁定,用以完成實際的構建任務。ide

內置綁定

爲了使用戶幾乎不用任何配置就能構建Maven項目,Maven在覈心爲一些主要的生命週期階段綁定了不少插件的目標,
當用戶經過命令行調用生命週期時,對應的插件目標就會執行相應的任務。
以下圖(default生命週期的階段與插件目標的綁定關係由項目打包類型決定(packaging元素)下圖以jar包構建爲例工具

生命週期 階段(phase) 內置插件 執行任務
clean pre-clean
clean maven-clean-plugin:clean 刪除項目的輸出目錄
post-clean
default vaildate
intianlize
generate-sources
proccess-sources
generate-resoureces
process-resources maven-resources-plugin:resources 複製主資源文件至主輸出目錄
compile maven-compiler-plugin:compile 編譯主代碼至主輸出目錄
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources maven-resources-plugin:testResources 複製測試資源文件至測試輸出目錄
test-compile maven-compiler-plugin:testCompile 編譯測試代碼至測試輸出目錄
process-test-classes
test maven-surefire-plugin:test 執行測試用例
prepare-package
package maven-jar-plugin:jar 建立項目jar包
pre-integration-test
integration-test
post-integration-test
verify
install maven-install-plugin:install 將項目輸出構件安裝到本地倉庫
deploy maven-deploy-plugin:deploy 將項目輸出構件安裝到遠程倉庫
site pre-site
site maven-site-plugin:site 生成項目站點
peo-site
site-deploy maven-site-plugin:deploy 將項目站點部署到遠程服務器上

Ps:空白的生命週期階段,默認沒有綁定任何插件,所以也沒有任何實際行爲
除默認打包類型jar外,常見的打包類型還有war、pom、maven-plugin、ear等。查看相關類型插件綁定官網http://maven.apache.org/guide...post

自定義綁定

除了內置綁定之外,用戶能夠選擇將某個插件目標綁定到生命週期的某個階段,能讓Maven項目在構建過程當中執行更多更富特點的任務。
如maven-source-plugin:jar-no-fork,可以將項目主代碼打成jar文件。將其綁定到default生命週期的verify階段上,在執行完繼承測試後和安裝構件以前建立源碼jar包。配置以下單元測試

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.0.1</version>
            <executions>    <!-- 插件執行配置 -->
                <execution>    <!-- executions下每一個execution子元素能夠配置執行一個任務 -->
                    <id>attach-sources</id>    <!-- 配置任務id -->
               <!-- <phase>verify</phase> -->  <!-- phase元素配置綁定生命週期階段 -->
                    <goals>    <!-- 配置要執行的插件目標 -->
                        <goal>jar-no-fork</goal>
                    </goals>
                <execution>
            </executions>
        </plugin>
    </plugins>
</build>

完成自定義插件綁定後,運行mvn verify便可。
在上述代碼中,註釋了phase元素也能實現綁定,緣由是不少插件目標在編寫時已經定義了默認綁定階段,可使用maven-help-plugin查看插件詳細信息,瞭解插件目標的默認綁定階段。
mvn help:describe -Dplugin=groupId:artifactId:version

當插件目標綁定到不一樣的生命週期時,其執行順序會由生命週期階段的前後順序決定。若是多個目標被綁定到同一個階段,這些插件聲明的前後順序決定目標的執行順序。

插件配置

完成插件目標與生命週期綁定後,用戶還能夠配置插件目標的參數,進一步調整插件目標所執行的任務,以知足項目的需求。幾乎全部Maven插件目標都有一些可配置參數,可經過命令行和POM配置等方式來配置參數。

1)命令行插件配置

使用-D參數,並伴隨一個參數名=參數值的形式,來配置參數
(命令行參數是由插件參數的表達式(Expression)決定,並不是全部插件目標參數都有表達式,只能在POM中配置)
如maven-surrfire-plugin插件提供了一個maven.test.skip參數,當其值爲true時,就會跳過執行測試。
mvn install -Dmaven.test.skip=true

2)POM中插件全局配置

並不是全部插件參數都適合從命令行配置,有些參數的值從項目構建到項目發佈都不會改變,或不多改變,在POM文件中一次性配置顯然比重複在命令行輸入要方便。
如mvan-compiler-plugin 能夠配置全局參數 實現compile以及testCompile任務都能使用全局配置。

<build>
    <plugins>
        <plugin>
            <groupId>...</groupId>
            <artifactId>...</artifactId>
            <version>...</version>
            <configuration>    <!-- 聲明插件全局配置 全部基於該插件目標的任務,都會使用這些配置 -->
                ...
            </configuration>
        </plugin>
    </plugins>
</builds>

3)POM中插件任務配置

除了爲插件配置全局的參數,還能夠爲某個插件任務配置特定的參數。
如maven-antrun-plugin 能夠配置插件任務參數,使run目標任務在不一樣生命週期輸出不一樣的語句。

<build>
    <plugins>
        <plugin>
            <groupId>...</groupId>
            <artifactId>...</artifactId>
            <version>...</version>
            <executions>
                <execution>
                    <id>...</id>
                    <phase>...</phase>
                    <goals>
                        <goal>...</goal>
                    </goals>
                    <configuration>    <!-- 插件任務一配置 -->
                        ...
                    </configuration>
                </execution>
                <execution>
                    <id>...</id>
                    <phase>...</phase>
                    <goals>
                        <goal>...</goal>
                    </goals>
                    <configuration>    <!-- 插件任務二配置 -->
                        ...
                    </configuration>
                </execution>
                ...
            </executions>
        </plugin>
    </plugins>
</builds>

獲取插件信息

僅僅理解如何配置使用插件是不夠的,實現一個構建任務,用戶需知道去哪找到合適的插件,並詳細瞭解該插件的配置點。因爲Maven的插件很是多,並且這其中大部分沒有完善的文檔,所以使用正確的插件並進行正確的配置,不容易。

1)在線插件信息

基本上全部的Maven插件都來自於apache和Codehaus。

apache 說明 官方插件,用戶多,穩定性好
詳細列表 http://maven.apache.org/plugi...
下載地址 http://repo1.maven.org/maven2...
Codehaus 說明 文檔和可靠性相對較差,遇到問題,每每須要本身看源碼
詳細列表 http://mojo.codehaus.org/plug...
下載地址 http://repository.codehaus.or...

雖然並不是全部插件都提供了完善的文檔,但一些核心插件的文檔仍是很是豐富的。
通常來講,經過閱讀插件在文檔中的使用介紹和實例,就應該可以在本身的項目中很好地使用該插件。
當咱們須要瞭解很是細節的目標參數時,就須要進一步訪問該插件每一個目標的文檔。文檔詳細解釋了該參數的做用、類型等信息。

2)使用maven-help-plugin插件

除了訪問在線的插件文檔以外,還能夠藉助maven-help-plugin來獲取插件的詳細信息。
執行maven-help-plugin的describe目標,指定要查詢的插件的座標,可查詢插件的座標,前綴(Goal Prefix),目標信息
mvn help:describe -Dplugin = (groupId:artifactId[:version] | Goal Prefix) -Dgoal = goal -Ddetail

從命令行調用插件

mvn -h 顯示mvn命令幫助,能夠看到以下信息:

usage:mvn [options] [<goal(s)]>] [<phase(s)>]
Options:
...

options表示可用的選項,除了選項以外,mvn命令後面能夠添加一個到多個goal和phase,分別指插件目標和生命週期階段。mvn命令能夠激活生命週期階段,從而執行那些綁定在生命週期階段上的插件目標。也能夠直接執行插件目標,由於有些插件目標不適用於生命週期階段,如maven-help-plugin:describe。
直接執行插件目標語法 在上文中已說起,可在插件目標中查看。

插件解析機制

在命令行中執行插件目標,可以使用插件前綴替代座標,方便用戶使用和配置插件。
Maven的這一特性是雙刃劍,雖然它簡化了插件的使用和配置,但若是出現問題,用戶很難定位出問題的插件構件。
如mvn help:system 執行了什麼插件。它的座標是什麼。這與Maven的插件解析機制有關。

1)插件倉庫

與依賴構件同樣,插件構件一樣基於座標存儲在Maven倉庫中,在須要的時候,Maven會先從本地倉庫尋找插件,不存在則從遠程倉庫找到插件,下載到本地倉庫使用。
插件的遠程倉庫不一樣於依賴的遠程倉庫,配置方式也不一樣,插件倉庫配置以下:

<pluginRepositories>
    <pluginRepository>
        ...    <!-- 此處與依賴遠程倉庫配置同樣,可參考閱讀總結二查看 -->
    </pluginRepository>
    ...
</pluginRepositoties>

Maven內置了插件倉庫指向中央倉庫,並關閉了對SNAPSHOT的支持。
通常來講,中央倉庫所包含的插件徹底可以知足咱們的須要,所以也不須要配置其餘的插件倉庫,只有在不多的狀況下,項目使用的插件沒法在中央倉庫找到,或者本身編寫了插件,能夠參考上述配置,在POM中或settings.xml中 加入其餘插件倉庫。

2)插件的默認groupId

在POM中配置插件時,若是該插件是Maven官方插件(groupId爲org.apache.maven.plugins),則能夠省略groupId配置。
不推薦使用這一特性,只省略一行配置,但會讓團隊中不熟悉Maven的成員感到費解。

3)解析插件版本

一樣爲了簡化插件的配置和使用,用戶可沒有提供插件的版本,Maven會自動解析插件版本。
首先,Maven在超級POM中爲全部核心插件設定了版本,超級POM是全部Maven項目的父POM,全部項目都繼承了這個超級POM配置。因此用戶使用插件未設定插件版本的狀況有如下幾種:

1 核心插件:經過超級POM繼承設定版本
2 非核心插件:經過倉庫元數據 groupId/artifactId/maven-metadata.xml ,遍歷並歸併本地倉庫和遠程倉庫的倉庫元數據,根據latest和release計算出插件的版本。Maven3以後使用release,避免使用latest獲取到快照版本,由於快照版本的頻繁更新會致使插件行爲的不穩定。

4)解析插件前綴

mvn命令行支持使用插件前綴來簡化插件的調用。Maven是如何經過插件前綴獲取插件的座標的?
插件前綴與groupId:artifactId是一一對應的,這種匹配關係存儲在倉庫元數據中,該倉庫員數據位於groupId/maven-metadate.xml,Maven在解析插件倉庫元數據時,會默認使用org.apache.maven.plugins和org.codehaus.mojo兩個groupId,能夠再settings.xml中配置其餘groupId

<settings>
    ...
    <pluginGroups>
        <pluginGroup>...</pluginGroup>
    </pluginGroups>
    ...
<settings>

插件倉庫元數據中存儲了全部插件前綴與group:artifactId的對應關係插件倉庫元數據檢查順序爲:apache -> codehaus -> 用戶自定義插件組 -> 都不包含該前綴,則報錯

相關文章
相關標籤/搜索