Maven強大的一個重要的原因,是它有一個十分完善的生命周期模型(Lifecycle)。
Maven的生命周期模型可以從兩個方面來理解
1.運行Maven的每個步驟都是由生命周期來定義的,這種預定義的默認行為將Maven的使用變得簡單。可以拿前輩Ant作為對比,因為Ant中的每個步驟都需要手工去定義,使用起來就會復雜很多。
2.生命周期模型是一種標准。在不同的項目中,使用Maven的接口是一樣的,這樣就不用去仔細地理解每個項目的構建了。因為一般情況下,mvn clean、mvn install這樣的命令是通用的。這一點也貫徹了【約定優於配置】的理念。
Maven有【三套】【相互獨立】的生命周期
Maven有三套獨立的生命周期,不了解的話很容易將Maven的生命周期看作一個整體。
1.清理生命周期(Clean Lifecycle):在開始真正的項目構建之前進行一些清理工作。
2.默認生命周期(Default Lifecycle):構建項目的核心部分,包括編譯、測試、打包、部署等。
3.站點生命周期(Site Lifecycle):生成項目報告、站點,發布站點。
相互獨立的意思就是說,你可以僅僅調用clean來清理工作目錄,可以僅僅調用site來生成站點,這三個生命周期之間相互獨立,並不存在強依賴關系。
當然了,也可以將三個生命周期組合使用,直接運行mvn clean install site來一起運行這三套生命周期。
清理生命周期(Clean Lifecycle)
每套生命周期都由一組階段(Phase)來組成,我們平時在控制台輸入的命令總是會對應於一個特定的階段,比如運行mvn clean,這里的clean就是清理生命周期的一個階段。
清理生命周期一共包含了三個階段:
1.pre-clean(預清理):執行一些需要在clean階段之前完成的工作。
2.clean(清理):移除所有上一次構建生成的文件。
3.post-clean(后清理):執行一些需要在clean結算之后立刻完成的工作。
mvn clean中的clean就是上面的clean。在一個生命周期中運行某個階段的時候,它之前的所有階段都會被運行,也就是說,mvn clean就相當於mvn pre-clean clean。如果我們運行mvn post-clean,那么pre-clean和clean都會被運行。這是Maven的一個很重要的規則/特性,可以大大地簡化命令的輸入。
默認生命周期(Default Lifecycle)
默認生命周期是Maven最重要的一個生命周期,絕大部分工作都發生在這個生命周期中。
默認生命周期包含了以下的階段(這里只列出常用和必要了解的,實際上還有很多):
process-resources:復制並處理資源文件,至目標目錄,准備打包。
compile:編譯項目的源代碼。
process-test-resources:復制並處理資源文件,至目標測試目錄。
test-compile:編譯測試源代碼。
test:使用合適的單元測試框架運行測試。這些測試代碼不會被打包或部署。
package:接受編譯好的代碼,打包成可發布的格式,如 JAR 。
install:將包安裝至本地倉庫,以讓其它項目依賴。
deploy:將最終的包復制到遠程的倉庫,以讓其它開發人員與項目共享。
其實默認生命周期中還提供了很多的階段,但是因為實際上會經常使用到的也就只有complie、test、package、install和deploy五個階段,這里也就不全部列出來了。想要了解所有的階段的話,可以到Maven的官方網站中查閱:http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html。
基本上,根據名稱我們就能猜出每個階段的用途。
站點生命周期(Site Lifecycle)
站點生命周期存在以下四個階段:
1.pre-site(預站點):執行一些需要在生成站點文檔之前的工作。
2.site(站點):生成項目的站點文檔。
3.post-site(后站點):執行一些需要在生成站點文檔之后完成的工作,並且為部署做准備。
4.site-deploy(站點部署):將生成的站點文檔部署到特定的服務器上。
在這些階段中,最常用到的是site階段和site-deploy階段,用以生成和發布Maven站點。這是Maven提供的一個相當強大的功能之一,深得管理者喜愛,因為文檔和統計數據能夠自動生成,並且很好看。
Maven生命周期的總結
Maven的生命周期的知識點比較簡單,在使用上只要記住,在同一套生命周期中運行任何一個階段的時候,它前面的所有階段都會被執行就行了。這就是為什么當我們運行mvn install命令的時候,代碼會被編譯(compile)、測試(test)和打包(package)。
但是這一特性在不同一套的生命周期中並不適用,比如很容易會認為清理生命周期是在默認生命周期之前的必經階段。也就是說,會被認為如果執行默認生命周期中的階段的話,清理生命周期中的所有階段都會被執行。而這是不對的,不同一套的生命周期之間是相互獨立的,其中的階段並不會相互影響。如果需要在打包之前先清理之前打包的內容,需要單獨運行清理生命周期。當然了,一般也會建議這么做,否則可能出現一些打包的奇怪問題,比如有一些文件並沒有被更新的問題。
另外需要注意的是,這些對項目及進行編譯、測試、打包、運行、部署等工作在Maven中都是抽象的定義,Maven自身是不會實際負責這些工作的,而是交由插件來實現。意思就是說,Maven命令的實際工作執行者是各種各樣的插件,通過插件提供的命令與Maven提供的階段相互綁定來完成相應的工作。因此Maven的插件機制是完全依賴於Maven的生命周期的,要想運用好這些Maven命令插件,理解Maven的生命周期也就變得十分重要。
上面這張圖是Idea開發工具中的Maven插件,只要理解了Maven的生命周期和其中的階段,就能很好地使用這個插件了。
"你說世界上真正值得說的事不多,就像真正過不去的坎也很少一樣。但是只要你願意給我說,我都想聽,不管值不值得;你過不去的坎,我也想陪你一起走,不管最終能不能走過。"