除了坐標、依賴以及倉庫之外,Maven的另外兩個核心概念是生命周期和插件。在有關Maven的日常使用中,命令行的輸入往往就對應了生命周期,如mvn package就表示執行默認生命周期階段package。Maven的生命周期是抽象的,其實際行為都由插件來完成,如package階段的任務可能就會由maven-jar-plugin完成。生命周期和插件兩者協同工作,密不可分。
1.Maven生命周期
我們在開發項目的時候,我們不斷地在經歷編譯、測試、打包、部署等過程,maven的生命周期就是對所有這些過程的一個抽象與統一,她的生命周期包含項目的清理、初始化、編譯、測試、打包、集成測試、驗證、部署、站點生成等幾乎所有的過程,而且maven的生命周期是及其靈活,她生命周期的每個階段是通過插件來實現的,maven也內置了很多插件,所以我們在項目進行編譯、測試、打包的過程是沒有感覺到。像編譯是通過maven-compile-plugin實現的、測試是通過maven-surefire-plugin實現的。
Maven有三套相互獨立的生命周期,請注意這裡說的是“三套”,而且“相互獨立”,初學者容易將Maven的生命周期看成一個整體,其實不然。這三套生命周期分別是:
我再次強調一下它們是相互獨立的,你可以僅僅調用clean來清理工作目錄,僅僅調用site來生成站點。當然你也可以直接運行 mvn clean install site運行所有這三套生命周期。
知道了每套生命周期的大概用途和相互關系以後,來逐個詳細看一下每套生命周期,Clean和Site相對比較簡單,先解釋一下:
每套生命周期都由一組階段(Phase)組成,我們平時在命令行輸入的命令總會對應於一個特定的階段。比如,運行mvn clean,這個的clean是Clean生命周期的一個階段。有點繞?要知道有Clean生命周期,也有clean階段。
Clean生命周期一共包含了三個階段:
mvn clean中的clean就是上面的clean,在一個生命周期中,運行某個階段的時候,它之前的所有階段都會被運行,也就是說,mvn clean等同於 mvn pre-clean clean,如果我們運行 mvn post-clean,那麼 pre-clean、clean 都會被運行。這是Maven很重要的一個規則,可以大大簡化命令行的輸入。
下面看一下Site生命周期的各個階段:
這裡經常用到的是site階段和site-deploy階段,用以生成和發布Maven站點,這可是Maven相當強大的功能,Manager比較喜歡,文檔及統計數據自動生成,很好看。
最後,來看一下Maven的最重要的Default生命周期,絕大部分工作都發生在這個生命周期中,這裡,我只解釋一些比較重要和常用的階段:
基本上,根據名稱我們就能猜出每個階段的用途,關於階段的詳細解釋以及其她階段的解釋,請參考 http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html 。
記住,運行任何一個階段的時候,它前面的所有階段都會被運行,這也就是為什麼我們運行mvn install的時候,代碼會被編譯,測試,打包。
此外,Maven的插件機制是完全依賴Maven的生命周期的,因此理解生命周期至關重要,接下來我將會進一步解釋Maven的插件機制。
2.命令行與生命周期
從命令行執行Maven任務的最主要方式就是調用Maven的生命周期階段。需要注意的是,各個生命周期是相互獨立的,而一個生命周期的階段是有前後依賴關系的。下面以一些常見的Maven命令為例,解釋其執行的生命周期階段:
mvn clean:該命令調用clean生命周期的clean階段。實際執行的階段為clean生命周期的pre-clean和clean階段。
mvn test:該命令調用default生命周期的test階段。實際執行的階段為default生命周期的validate、initialize等,直到test的所有階段。這也解釋了為什麼在執行測試的時候,項目的代碼能夠自動得以編譯。
mvn clean install:該命令調用clean生命周期的clean階段和default生命周期的install階段。實際執行的階段為clean生命周期的pre-clean、clean階段,以及default生命周期的從validate至install的所有階段。該命令結合了兩個生命周期,在執行正在的項目構建之前清理項目是一個很好的實踐。
mvn clean deploy site-deploy:該命令調用clean生命周期的clean階段、default生命周期的deploy階段,以及site生命周期的site-deploy階段。實際執行的階段為clean生命周期的pre-clean、clean階段,default生命周期的所有階段,以及site生命周期的所有階段。該命令結合了Maven所有三個生命周期,且deploy為default生命周期的最後一個階段,site-deploy為site生命周期的最後一個階段。
由於Maven中主要的生命周期階段並不多,而常用的Maven命令實際都是基於這些階段簡單組合而成的,因此只要對Maven生命周期有一個基本的理解,讀者就可以正確而熟練地使用Maven命令。
3.Maven插件機制
通過上面的生命周期我們可以了解到,不同的生命周期綁定不同的插件;同時我們知道,下載下來的maven核心的東西不過3-4M,它主要就是通過插件來完成這些工作的,一旦碰到沒有的插件,它會跑到相應的地方下載,然後來完成整個過程。那麼在我們的項目中如何使用插件呢?
打開http://maven.apache.org/plugins/index.html網址,我們可以看到apache下面的很多插件,apache下面的插件是比較正規的,它裡面的信息非常詳細。下面我們來看看裡面有個source的插件的用法。
Source插件是對源代碼進行打包的一個插件,默認情況下,它會將生成的源代碼放在工程目錄的target下面。
Source插件具有五個目標:
在我們的工程pom.xml中,在後面引入下面這段配置:
1 <build> 2 <plugins> 3 <plugin> 4 <groupId>org.apache.maven.plugins</groupId> 5 <artifactId>maven-source-plugin</artifactId> 6 <version>2.1.2</version> 7 </plugin> 8 </plugins> 9 </build>
上面這段配置就是對源碼進行打包的插件,我們運行source:jar-no-fork,那麼在項目的目錄底下的target會生成一個類似於user-core-0.0.1-SNAPSHOT-sources.jar這樣的文件,即項目的源文件。那麼如何將這個插件與特定的生命周期綁定呢?我們來看下面這段配置:
1 <build> 2 <plugins> 3 <plugin> 4 <groupId>org.apache.maven.plugins</groupId> 5 <artifactId>maven-source-plugin</artifactId> 6 <version>2.1.2</version> 7 <executions> 8 <execution> 9 <phase>package</phase> 10 <goals> 11 <goal>jar-no-fork</goal> 12 </goals> 13 </execution> 14 </executions> 15 </plugin> 16 </plugins> 17 </build>
通過這段配置,大家可以用 mvn package 將項目打包的同時會將源代碼進行打包。圖示說明:
Apache Maven裡面還有很多有用的插件,大家可以自己去試一下,裡面說明很詳細,大家只要按著官方文檔進行配置,一般情況下是沒問題的,如果大家想把插件用的非常熟練建議多請教請教大神,或者購買《Maven實戰》書籍,書籍中對插件會介紹的更詳細,然後再結合大神使用的經驗,相信大家能夠熟練地使用Maven插件機制。
結束語:今天走的路,你要記在心裡,無論你與目標之間有多遠,也要學會輕松地走路。只有這樣,在走向目標的過程中,才不會感到煩悶,才不會被遙遠的未來所嚇倒。