以下引用官方的生命周期解釋https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html:
一、構建生命周期基礎:
Maven基於構建生命周期的中心概念。這意味着構建和分發特定工件(項目)的過程被明確定義。
對於構建項目的人員,這意味着只需要學習一小堆命令即可構建任何Maven項目,POM將確保他們獲得所需的結果。
有三個內置的生命周期:默認(default),清潔(clean)和站點(site)。在默認(default)的生命周期處理你的項目部署,將清潔(clean)的生命周期處理項目的清理,而網站(site)的生命周期處理你的項目站點文檔的創建。
二、構建生命周期是由階段組成的:
這些構建生命周期中的每一個由構建階段的不同列表定義,其中構建階段表示生命周期中的階段。
例如,默認(default)的生命周期包括以下階段(注意:這里是簡化的階段,用於生命周期階段的完整列表,請參閱下方生命周期參考):
驗證(validate) - 驗證項目是否正確,所有必要的信息可用
編譯(compile) - 編譯項目的源代碼
測試(test) - 使用合適的單元測試框架測試編譯的源代碼。這些測試不應該要求代碼被打包或部署
打包(package) - 采用編譯的代碼,並以其可分配格式(如JAR)進行打包。
驗證(verify) - 對集成測試的結果執行任何檢查,以確保滿足質量標准
安裝(install) - 將軟件包安裝到本地存儲庫中,用作本地其他項目的依賴項
部署(deploy) - 在構建環境中完成,將最終的包復制到遠程存儲庫以與其他開發人員和項目共享。
這些生命周期階段(以及此處未顯示的其他生命周期階段)依次執行,以完成默認生命周期。給定上述生命周期階段,這意味着當使用默認生命周期時,Maven將首先驗證項目,然后嘗試編譯源代碼,運行這些源代碼,打包二進制文件(例如jar),運行集成測試軟件包,驗證集成測試,將驗證的軟件包安裝到本地存儲庫,然后將安裝的軟件包部署到遠程存儲庫。
換句話說,在生命周期里面階段是連續的,在不出錯的前提下,比如執行打包(package)時就一定是執行了測試(test)之后再執行。
三、生命周期參考:
以下列出了默認(default),清潔(clean)和站點(site)生命周期的所有構建階段,它們按照指定的順序執行的順序執行。
清潔(clean)生命周期
預清潔(pre-clean) 執行實際項目清理之前所需的流程
清潔(clean) 刪除以前構建生成的所有文件
后清潔(post-clean) 執行完成項目清理所需的流程
默認(default)生命周期
驗證(validate) 驗證項目是正確的,所有必要的信息可用。
初始化(initialize) 初始化構建狀態,例如設置屬性或創建目錄。
產生來源(generate-sources) 生成包含在編譯中的任何源代碼。
流程源(process-sources) 處理源代碼,例如過濾任何值。
生成資源(generate-resources) 生成包含在包中的資源。
流程資源(process-resources) 將資源復制並處理到目標目錄中,准備打包。
編譯(compile) 編譯項目的源代碼。
工藝類(process-classes) 從編譯后處理生成的文件,例如對Java類進行字節碼增強。
生成測試來源(generate-test-sources) 生成包含在編譯中的任何測試源代碼。
流程測試來源(process-test-sources) 處理測試源代碼,例如過濾任何值。
生成測試資源(generate-test-resources) 創建測試資源。
流程測試資源(process-test-resources) 將資源復制並處理到測試目標目錄中。
測試編譯(test-compile) 將測試源代碼編譯到測試目標目錄中
流程檢驗類(process-test-classes) 從測試編譯中處理生成的文件,例如對Java類進行字節碼增強。對於Maven 2.0.5及以上版本。
測試(test) 使用合適的單元測試框架運行測試。這些測試不應該要求代碼被打包或部署。
制備包(prepare-package) 在實際包裝之前,執行必要的准備包裝的操作。這通常會導致打包的處理版本的包。(Maven 2.1及以上)
打包(package) 采取編譯的代碼,並以其可分發的格式(如JAR)進行打包。
預集成測試(pre-integration-test) 在執行集成測試之前執行所需的操作。這可能涉及諸如設置所需環境等。
集成測試(integration-test) 如果需要,可以將該包過程並部署到可以運行集成測試的環境中。
整合后的測試(post-integration-test) 執行集成測試后執行所需的操作。這可能包括清理環境。
校驗(verify) 運行任何檢查以驗證包裝是否有效並符合質量標准。
安裝(install) 將軟件包安裝到本地存儲庫中,以作為本地其他項目的依賴關系。
部署(deploy) 在集成或發布環境中完成,將最終軟件包復制到遠程存儲庫,以與其他開發人員和項目共享。
站點(site)生命周期
預網站(pre-site) 在實際的項目現場生成之前執行所需的進程
網站(site) 生成項目的站點文檔
后網站(post-site) 執行完成站點生成所需的進程,並准備站點部署
網站部署(site-deploy) 將生成的站點文檔部署到指定的Web服務器
四、生命周期階段在命令行中的調用
在開發環境中,使用以下調用構建並將工件安裝到本地存儲庫中。
mvn install
此命令在執行安裝之前按順序(驗證(validate),編譯(compile),打包(package)等)執行每個默認生命周期階段。在這種情況下,您只需要調用最后一個構建階段來執行,安裝(install)。
在構建環境中,使用以下調用將工件清理地構建並部署到共享存儲庫中。
mvn clean deploy
相同的命令可以在多模塊場景(即具有一個或多個子項目的項目)中使用。Maven遍歷每個子項目並執行清潔(clean),然后執行部署(deploy)(包括所有之前的構建階段步驟)。
注意:在我們開發階段,有一些生命周期的階段,比如驗證(validate)這些,基本很少用到。只要使用關鍵的幾個基本能滿足需求。
五、通常情況在命令行只調用某些特定的階段
以連字符(pre-*,post-或process-)命名的階段通常不會從命令行直接調用。這些階段對構建進行排序,生成在構建之外無用的中間結果。在調用集成測試的情況下,環境可能處於掛起狀態。
諸如Jacoco和執行容器插件(如Tomcat,Cargo和Docker)的代碼覆蓋工具將目標綁定到預集成測試(pre-integration-test)階段以准備集成測試容器環境。這些插件還將目標綁定到整合后的測試(post-integration-test)階段,以收集覆蓋統計信息或停止集成測試容器。
故障安全和代碼覆蓋插件將目標綁定到集成測試(integration-test)和驗證(verify)階段。最終結果是在驗證(verify)階段后可以使用測試和覆蓋率報告。如果從命令行調用集成測試(integration-test)階段,則不會生成任何報告。整合測試容器環境處於更糟糕的懸掛狀態; Tomcat網絡服務器或Docker實例將保持運行,並且Maven本身甚至可能不會終止。
提示:再次明確,在生命周期的階段上,只有特定的幾個階段對於構建有意義。一些無用的階段只起到了中間階段的作用,換句話說只是一個過客。
六、調用由插件目標(Plugin Goals)組成的構建階段
然而,即使構建階段負責構建生命周期中的特定步驟,其執行這些職責的方式可能會有所不同。這是通過聲明綁定到這些構建階段的插件目標來完成的。
插件目標代表一個特定的任務(比構建階段更精細),有助於項目的構建和管理。它可能被限制在零個或多個構建階段。不限於任何構建階段的目標可以通過直接調用在構建生命周期之外執行。執行順序取決於調用目標和構建階段的順序。例如,考慮下面的命令。該清潔(clean)和打包(package)是建立階段,而dependency:copy-dependencies是(一個插件)的目標。
mvn clean dependency:copy-dependencies package
如果要執行此操作,則將首先執行清潔(clean)階段(意味着它將運行清潔生命周期的所有先前階段以及清潔(clean)階段本身),然后執行dependency:copy-dependencies目標,然后才能最終執行打包(package)階段(以及默認生命周期的所有之前的構建階段)。
而且,如果一個目標被綁定到一個或者多個構建階段,那么在所有這些階段都會調用這個目標。
此外,構建階段也可以有零個或多個目標。如果構建階段沒有綁定目標,則構建階段將不會執行。但是,如果它有一個或多個目標,它將執行所有這些目標(注意:在Maven 2.0.5及更高版本中,綁定到階段的多個目標的執行順序與POM中聲明的順序相同,但不支持同一插件的多個實例,同一個插件的多個實例被分組一起執行要在Maven 2.0.11及以上)。
提示:其實簡單點理解就是說dependency是一個插件,在我們執行生命周期階段時,可以調用這個插件做特定的事,其中copy-dependencies就是特定的事,那么上面的命令可以這么理解,在執行clean后就會執行dependecy這個插件,最后再執行package;如果dependecy這個插件執行過程異常,package就不會執行到。還有就是一個命令可以有多個插件,也可以一個插件都沒有。
提示2:dependency:copy-dependencies這樣的形式最標准的官方說法:左邊dependency為插件,右邊copy-dependencies為插件的目標,通常還有一種說法就是命令行參數。
七、使用構建生命周期來設置項目
構建生命周期足夠簡單,但是當您為項目配置Maven構建時,您如何將任務分配到每個構建階段?
打包
第一個也是最常見的方法是通過同樣命名的POM元素為您的項目設置打包。一些有效的打包值是jar,war,ear和pom。如果沒有指定包裝值,它將默認為jar。
每個不同類型的打包都包含要綁定到特定階段的目標列表。例如,jar包將綁定以下目標來構建默認生命周期的階段。
流程資源(process-resources) resources:resources
編譯(compile) compiler:compile
流程測試資源(process-test-resources) resources:testResources
測試編譯(test-compile) compiler:testCompile
測試(test) surefire:test
打包(package) jar:jar
安裝(install) install:install
部署(deploy) deploy:deploy
這幾乎是一個標准的綁定 ; 然而,一些包裝處理它們不同。例如,純粹的元數據(包裝值是pom)的項目只將目標綁定到安裝(install)和部署(deploy)階段(對於某些包裝類型的目標到構建階段綁定的完整列表,請參閱生命周期參考)。
請注意,對於某些可用的打包類型,您可能還需要在POM的部分中包含一個特定的插件,並為該插件指定true。需要這種插件的一個例子是Plexus插件,它提供plexus-application和plexus-service打包。
提示:這里簡單點可以說不同的包對應不同的生命周期階段,比如jar包和war包的區別可以參考:https://maven.apache.org/ref/3.5.0/maven-core/default-bindings.html。上方列表可以這么理解,左邊是簡化的命令,右側是詳細的插件加目標(命令行參數)的形式;切記,Maven都是以插件的形式存在的,包括生命周期的階段同樣也是一個個不同的插件組成,比如上面的編譯(compile)就是由compiler插件提供,其中compile為這個插件的目標,也可以說是插件的命令行參數。
插件
將目標添加到階段的第二種方法是在項目中配置插件。插件是為Maven提供目標的工件。此外,插件可以具有一個或多個目標,其中每個目標代表該插件的能力。例如,編譯器(compiler)插件有兩個目標:compile和testCompile。前者編譯主代碼的源代碼,后者編譯測試代碼的源代碼。
如稍后部分所示,插件可以包含指示將目標綁定到的生命周期階段的信息。請注意,自己添加插件是不夠的,您還必須指定要作為構建的一部分運行的目標。
配置的目標將被添加到已經從選定的打包綁定到生命周期的目標。如果將多個目標綁定到特定階段,則使用的順序是首先執行來自打包裝的順序,然后執行在POM中配置。請注意,您可以使用元素來獲得對特定目標的順序更多的控制。
例如,Modello插件默認將目標modello:java綁定到generate-sources階段(注意:modello:java目標生成Java源代碼)。因此,要使用Modello插件,並從模型生成源代碼並將其合並到構建中,您可以在的部分中將以下內容添加到POM中:
…
< plugin>
< groupId>org.codehaus.modello< /groupId>
< artifactId>modello-maven-plugin< /artifactId>
< version>1.8.1< /version>
< executions>
< execution>
< configuration>
< models>
< model>src/main/mdo/maven.mdo< /model>
< /models>
< version>4.0.0< /version>
< /configuration>
< goals>
< goal>java< /goal>
< /goals>
< /execution>
< /executions>
< /plugin>
…
復制代碼
提示:這里所說的更直白的意思就是Modello插件有默認的生命周期階段,而無需自己手動配置這些階段。
你可能會想知道為什么這個元素在那里。這樣,如果需要,您可以使用不同的配置多次運行相同的目標。還可以使用單獨的執行標識,以便在繼承或應用配置文件期間,您可以控制目標配置是合並還是轉為額外的執行。
當給出與特定階段匹配的多個執行時,它們按照POM中指定的順序執行,繼承的執行首先運行。
現在,在modello:java的情況下,它只在generate-sources階段才有意義。但是一些目標可以在一個以上的階段中使用,也可能沒有合理的默認。對於那些,您可以自己指定階段。例如,假設您有一個目標display:time當前時間到命令行的時間,並希望它在process-test-resources階段運行以指示測試何時開始。這將被配置如下:
/* …
< plugin>
< groupId>com.mycompany.example
< artifactId>display-maven-plugin
< version>1.0
< executions>
< execution>
< phase>process-test-resources
< goals>
< goal>time
< /goals>
< /execution>
< /executions >
< /plugin>
…*/
復制代碼
提示:這里已經是換了一個插件了,與上面的插件不同的是,可以在中指定生命周期階段。可以說是兩個做了一個明顯對比。
八、內置生命周期的綁定
根據https://maven.apache.org/ref/3.5.0/maven-core/default-bindings.html提供的不同類型對應不同的生命周期階段
默認情況下,某些階段的目標與之相關。對於默認生命周期,這些綁定取決於包裝值。以下是一些目標到構建階段的綁定。
清潔生命周期綁定
清潔(clean) clean:clean
默認生命周期綁定-打包ejb/ejb3/jar/par/rar/war
流程資源(process-resources) resources:resources
編譯(compile) compiler:compile
流程測試資源(process-test-resources) resources:testResources
測試編譯(test-compile) compiler:testCompile
測試(test) surefire:test
打包(package) ejb:ejb or ejb3:ejb3 or jar:jar or par:par or rar:rar or war:war
安裝(install) install:install
部署(deploy) deploy:deploy
默認生命周期綁定-打包ear
生成資源(generate-resources) ear:generate-application-xml
流程資源(process-resources) resources:resources
打包(package) ear:ear
安裝(install) install:install
部署(deploy) deploy:deploy
默認生命周期綁定-打包maven-plugin
生成資源(generate-resources) plugin:descriptor
流程資源(process-resources) resources:resources
編譯(compile) compiler:compile
流程測試資源(process-test-resources) resources:testResources
測試編譯(test-compile) compiler:testCompile
測試(test) surefire:test
打包(package) jar:jar and plugin:addPluginArtifactMetadata
安裝(install) install:install
部署(deploy) deploy:deploy
默認生命周期綁定-包裝pom
打包(package) site:attach-descriptor
安裝(install) install:install
部署(deploy) deploy:deploy
網站生命周期綁定
網站(site) site:site
網站部署(site-deploy) site:deploy
九、一些參考
完整的Maven生命周期由maven-core模塊中的components.xml文件定義,並附有相關文檔供參考。
Maven中2.x中,默認的生命周期的綁定被納入的components.xml,但在Maven的3.x中,它們在一個單獨的被定義default-bindings.xml描述符。
請參閱生命周期參考和插件綁定,以獲取直接從源代碼獲取的最新文檔的默認生命周期參考。
總結:
1、整體來自官方文檔,中文來自谷歌翻譯,文中難免有一些直譯的錯誤,但是不影響理解。
2、文中的提示為自己的個人理解。
3、在理解生命周期時市面上的說法沒有官方來的更直接更明了。
4、切記所有的生命周期的階段都是以插件的形式存在的,或者這么說吧,Maven的一切就是一個大插件包集合。
5、文中提到的目標,我理解成了命令行參數,比如dependency:copy-dependencies整體就是叫做目標,而我喜歡把copy-dependencies叫做目標,dependency叫做插件。