介紹maven建構的生命周期
這篇是 https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html 的譯文。
建構生命周期的基礎知識
建構的生命周期是maven的最核心概念。它的意思就是建構和釋出某個特定的artifact(project)的每個階段是否清晰定義。
對想要建構一個project的開發人員來說,隻需要掌握非常少的指令,就可以編譯一個maven的項目,pom會保證會生成我們希望的産出結果。
有三個内置的建構周期:default,clean 和site。default周期處理項目的部署。clean周期處理項目的清理。site周期建立項目的站點文檔。
建構的生命周期由階段組成
每個生命周期都由一些不同的建構階段組成。每個建構階段都是生命周期的一個步驟。
例如,default生命周期由下面的階段組成:
-
- validate - 驗證項目是否正确,并且所有必要的資訊是否有效
- compile - 編譯項目的代碼
- test - 使用合适的單元測試架構測試源碼。這些測試代碼并不要求打包或者部署
- package - 擷取編譯後的代碼,并且把它們打成可派發的格式,比如JAR.
- verify - 運作內建測試,以確定項目符合品質标準
- install - 安裝包到本地的repository中,以便其他項目可以依賴這個項目。
- deploy - 在建構的結束階段,把最終包上傳到遠端的repository中,以便其他的項目和開發者可以使用。
這些建構周期的各個步驟是用來順序執行,以便完成default的生命周期。(當然其他的生命周期的步驟還沒有介紹)。這就意味着,一旦使用了default生命周期,maven會首先驗證項目,然後編譯代碼,跑單元測試,打包二進制檔案,運作內建測試,驗證內建測試,安裝驗證後的包到本地倉庫,然後部署到遠端倉庫。
使用指令行調用
在開發環境,使用下面的指令建構和安裝項目到本地倉庫
mvn install
這個指令執行default生命周期中install階段及之前的階段(比如validate,compile,package等)。就是說,你隻需要調用最後一個需要你執行的階段就能執行這個階段之前的指令了。
在建構環境,使用下面的指令就能清空建構釋出在共享倉庫中的項目。
mvn clean deploy
在多子產品場景,maven進入到每個子項目并且執行clean,然後執行deploy。
一個建構的過程是由插件的目标組成
雖然一個建構過程是為建構生命周期的某個階段負責,但是,實作這個階段的方法有多種多樣。這些方法是由綁定再這些編譯階段的插件的目标來實作的。
一個插件的目标代表一個用于建構和管理項目的任務(任務的概念比建構過程更為精細)。一個任務可以被綁定在零個或者多個建構過程上。沒有被綁定在任何建構過程的目标也可以被直接調用。執行的順序由目标和建構過程調用的順序來定。例如,下面的指令。clean和package是建構過程,dependency:copy-dependencies是一個插件的目标。
mvn clean dependency:copy-dependencies package
執行這個指令,clean建構過程會被執行(意味着它執行clean建構過程之前的所有過程),然後dependency:copy-dependencies目标會被執行,最後,執行package建構過程(及前面所有的建構過程)。
如果一個目标綁定在一個或者多個建構階段,這個目标會被所有建構階段調用。
換句話說,一個建構階段可以由零個或者多個目标綁定。如果一個建構階段沒有目标綁定,那麼這個建構階段就不會執行。但是一旦有一個或者多個目标綁定,它就會執行這些目标。
(注意:在Maven 2.0.5及之上,一個建構階段的多個目标的執行順序,是和這些目标在POM中聲明的順序一緻的。但是,多個相同的插件是不允許的。在Maven2.0.11及以上版本,要是定義了多個相同插件,他們會被分組并且一起執行。)
一些建構階段一般不會通過指令行進行調用
一些由複合詞(pre-*, post-*, process-*)組成的建構階段通常不會由指令行直接調用。這些建構過程連接配接整個建構流程,産生不被外部使用的中間結果。例如調用integration-test階段,整個環境會停留在懸挂狀态。
代碼覆寫工具,例如Jacoco,執行容器插件,例如Tomcat,Cargo和Docker把目标綁定在pre-integration-test階段,用于準備測試的容器環境。這些插件也綁定在post-integration-test階段,用于收集覆寫率的統計,或者回收測試容器。
故障保護和代碼覆寫插件綁定目标在integration-test和verify階段。最終的結果就是在verify階段之後生成可用的測試和代碼覆寫率報告。如果integration-test由指令行調用,就不會生成任何的報告。更糟糕的是,遷移測試的容器環境就會停留在懸挂狀态。Tomcat服務和Docker執行個體就會一直運作,maven不會自己終止。
使用建構生命周期來搭建項目
建構的生命周期是很容易使用的。但是具體當我們考慮使用maven建構一個項目的時候,如何為每個建構過程指定任務呢?
Packaging
首先,最通用的方法,通過POM中的元素為你的項目設定打包方式。一些可用的打包的值為jar, war, ear, 和pom。如果沒有設定packing的值,預設為jar。
每個packaging會由一些特定的目标綁定在特定的任務中,比如,jar打包方式會綁定下面的目标在預設的生命周期中。

上圖差不多就是基本的綁定設定。但是一些打包方式是不一樣的設定。例如,純元項目的打包方式(pom)隻綁定了install和deploy建構階段。
注意,除了預設的,一些額外的打包方式也是可以額外擷取。你可以使用pom檔案的标簽來引入一個特定的插件,并且指定true。比如Plexus插件提供plexus-application和plexus-service打包方式。
Plugins
第二種把目标增加到建構階段的方法是在你的項目中配置插件。插件就是提供目标給maven的項目。或者說,插件可以有一個或者多個目标,每個目标代表插件的一種能力。例如,Compiler插件有兩個目标:compile和testCompile。前者編譯你的主代碼,後者編譯你的測試代碼。
在後面的章節你會看到,插件包含希望在什麼建構階段插入目标的資訊。注意,插件自己并沒有這個資訊-你必須指定你想要在哪個編譯階段使用這個目标。
目标可以配置到那些已經被Packaging綁定的建構階段中。如果多個目标綁定到一個特定階段,執行的順序是,先執行packaging中的目标,再執行配置檔案POM配置的目标。注意,你可以通過來控制某些特定目标的執行順序。
例如,Modello插件會将modello:java目标綁定到generate-source階段(注意:modello:java目标會生成java代碼)。是以,使用Modello插件并且讓它生成代碼并且将代碼加入到build階段,你需要加下面的到:
...
<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>
...
你也許會很好奇為什麼标簽存在。這樣你就可以根據不同的配置檔案執行多次相同的目标。每個excuteion可以配置一個唯一的ID,在繼承或者應用權限階段,你可以控制是否合并目标配置檔案,還是作為一個額外的執行。
當多個executions被配置給一個單獨的過程,它們會按照POM中配置的中的順序執行。
例如,modello:java,它隻在generate-source建構階段生效。但是一些目标卻會在一個或者多個建構階段執行,并且這些目标并不強制要求按照預設階段執行。對這些,你就需要自己來配置了。例如,你有一個目标display:time,這個目标是列印目前時間到控制台,如果你希望它在process-test-resources階段執行,以便告知什麼時候測試開始執行,你就需要配置如下:
...
<plugin>
<groupId>com.mycompany.example</groupId>
<artifactId>display-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<phase>process-test-resources</phase>
<goals>
<goal>time</goal>
</goals>
</execution>
</executions>
</plugin>
...
生命周期相關參考
下面是default, clean 和site生命周期的所有建構階段,按照下文所示的順序執行。
clean生命周期
-
- pre-clean: execute processes needed prior to the actual project cleaning
- clean: remove all files generated by the previous build
- post-clean: execute processes needed to finalize the project cleaning
default生命周期
-
- validate: validate the project is correct and all necessary information is available.
- initialize: initialize build state, e.g. set properties or create directories.
- generate-sources: generate any source code for inclusion in compilation.
- process-sources: process the source code, for example to filter any values.
- generate-resources: generate resources for inclusion in the package.
- process-resources: copy and process the resources into the destination directory, ready for packaging.
- compile: compile the source code of the project.
- process-classes: post-process the generated files from compilation, for example to do bytecode enhancement on Java classes.
- generate-test-sources: generate any test source code for inclusion in compilation.
- process-test-sources: process the test source code, for example to filter any values.
- generate-test-resources: create resources for testing.
- process-test-resources: copy and process the resources into the test destination directory.
- test-compile: compile the test source code into the test destination directory
- process-test-classes: post-process the generated files from test compilation, for example to do bytecode enhancement on Java classes. For Maven 2.0.5 and above.
- test: run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed.
- prepare-package: perform any operations necessary to prepare a package before the actual packaging. This often results in an unpacked, processed version of the package. (Maven 2.1 and above)
- package: take the compiled code and package it in its distributable format, such as a JAR.
- pre-integration-test: perform actions required before integration tests are executed. This may involve things such as setting up the required environment.
- integration-test: process and deploy the package if necessary into an environment where integration tests can be run.
- post-integration-test: perform actions required after integration tests have been executed. This may including cleaning up the environment.
- verify: run any checks to verify the package is valid and meets quality criteria.
- install: install the package into the local repository, for use as a dependency in other projects locally.
- deploy: done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.
site生命周期
-
- pre-site: execute processes needed prior to the actual project site generation
- site: generate the project's site documentation
- post-site: execute processes needed to finalize the site generation, and to prepare for site deployment
- site-deploy: deploy the generated site documentation to the specified web server
内置的生命周期綁定目标
一些生命周期已經綁定了一些目标。這些預設的生命周期,依賴packaging值不同有不同的目标。下面是一些建構階段的目标: