Maven
的生命周期是對所有構建過程的抽象和統一。包含了項目的清理、初始化、編譯、測試、打包、集成測試、驗證、部署和站點生成等幾乎所有構建步驟。
Maven
的生命周期是抽象的,其實際行為是由插件來完成的,生命周期和插件兩者協同合作,密不可分。
這種思想與設計模式中的模板方法非常相似。模板方法模式在父類定義算法的整體結構,子類通過實現或者重寫父類的方法來控制實際行為,這樣既能保證算法有足夠的可擴展性,又能嚴格控制算法的整體結構。
4.1 生命周期
Maven
擁有3套獨立的生命周期:clean
、default
、site
。
clean
生命周期的目的是清理項目。
default
生命周期的目的是構建項目。
site
生命周期的目的是建立項目站點。
每個生命周期包含一些階段(phase
),這些階段是有序的,后面的階段會依賴于前面的階段。
4.1.1 clean生命周期
clean
生命周期的3個階段:
pre-clean
:執行一些清理前需要完成的動作clean
:清理上一次構建生成的文件post-clean
:執行一些清理后需要完成的動作
4.1.2 default生命周期:
validate
initialize
generate-sources
process-sources
處理項目主資源文件,一般來說,是對src/main/resources
目錄的內容進行變量替換等工作,復制到項目輸出的主classpath
目錄中。generate-resources
process-resources
compile
編譯項目的主源碼到主classpath
目錄中。process-classes
generate-test-sources
process-test-sources
處理項目測試資源文件,一般來說,是對src/test/resources
目錄的內容進行變量替換等工作,復制到項目輸出的測試classpath
目錄中。
11)generate-test-resources
12)process-test-resources
test-compile
編譯項目的測試源碼到測試classpath
目錄中。process-test-classes
15)test
使用單元測試框架進行測試,測試代碼不會被打包或部署
prepare-package
package
將編譯好的代碼,打包成可發布的格式,如jar
pre-integration-test
19)integration-test
post-integration-test
verify
22)install
將包安裝到Maven
本地倉庫,供本地其他Maven
項目使用
-
deploy
將最終的包復制到遠程倉庫,供其他開發人員和Maven
項目使用
4.1.3 site生命周期
site
生命周期的目的是建立和發布項目站點,Maven
能夠基于POM
所包含的信息,自動生成一個友好的站點,方便團隊交流和發布項目信息,含如下階段:
1)pre-site
執行一些在生成項目站點之前需要完成的工作
2)site
生成項目站點文檔
post-site
執行一些在生成項目站點之后需要完成的工作site-deploy
將生成的項目站點發布到服務器上
4.2 插件目標
對于一個插件,為了復用代碼,它往往能夠完成多個任務,例如maven-dependency-plugin
,能夠分析項目依賴;列出項目依賴樹;列出項目已解析的依賴,為這樣每個功能獨立編寫一個插件,顯然是不可取的,因為這些功能背后有相同的代碼,因此將這些功能聚集在一個插件里,每個功能就是一個插件目標。
4.3 插件綁定
Maven
的生命周期與插件相互綁定,用于完成實際的構建任務,具體而言,是生命周期的階段與插件的目標相互綁定,以完成某個具體的構建任務。
下面是一些內置的綁定:
maven-clean-plugin
只有一個clean
目標
項目的打包類型會影響構建的具體過程,因此default
生命周期的階段與插件目標的綁定關系由項目的打包類型所決定,下面以jar
為示例:
除了內置綁定外,用戶能夠自己選擇將某個插件目標綁定到生命周期的某個階段上,以便在項目構建過程中執行更豐富的任務。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<id>attach-source</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
除了基本的插件坐標配置,<executions>
下的每個<execution>
用來配置執行一個任務。有時候,即使不配置<phase>
階段,插件目標也能綁定到生命周期中去,這是因為很多插件的目標在編寫時已經定義了默認的綁定階段,可以通過maven-help-plugin
查看插件的詳細信息:
mvn help:describe –Dplugin=org.apache.maven.plugins:maven-source-plugin:2.1.1 -Ddetail
4.4 插件解析機制
為了方便用戶使用和配置插件,Maven
不需要用戶提供完整的插件坐標信息,就可以解析得到正確的插件。
與依賴構件一樣,插件構件同樣基于坐標存儲在Maven
倉庫中,但Maven
會區別對待依賴的遠程倉庫與插件的遠程倉庫。
通過<repositories>
及其子元素<repository>
可以配置依賴的遠程倉庫,插件的遠程倉庫需要使用<pluginRepositories>
和<pluginRepository>
進行配置。
默認情況下,如果該插件是Maven
官方插件,則可以省略groupId
(org.apache.maven.plugins
),Maven
在解析該插件的時候,會自動將groupId
補上。
當插件沒有添加版本號時,若該插件是核心插件,則在超級POM
已經定義了版本號,若不是核心插件,Maven
會遍歷本地倉庫和遠程倉庫,計算出latest
和release
的值,Maven 2
使用latest
,但因為latest
可能是快照版本,Maven 3
更改為使用release
。