maven學習之路(四)生命週期和外掛
1、什麼是生命週期?外掛的作用?
前面我們說過,maven是一個專案構建、依賴管理的工具,生命週期就是maven在專案構建的過程中抽象出來的一系列子過程,例如編譯、執行測試、打包等等過程。 需要注意的是,maven只是將生命週期進行了抽象化的定義,真正實現生命週期各個過程是外掛。這樣做的好處是,可以最大限度的將定製構建行為的能力提供給開發人員,開發人員甚至可以自己編寫自己需要的外掛,來滿足自己的特性化構建需求。
2、maven的生命週期
2.1、maven的三套生命週期
對於maven的生命週期來說,共有三個相互獨立的生命週期,分別是clean、default、site。
- clean生命週期目的是清理專案
- default生命週期目的是構建專案
- site生命週期目的是建立專案站點。
每個生命週期分別包含一些階段,這些階段是有順序的,並且後面的階段依賴於前面的階段。如clean生命週期包含pre-clean、clean和post-clean三個階段,如果執行clean階段,則會先執行pre-clean階段。 較之於生命週期階段有前後依賴關係,三套生命週期本身是相互獨立的,使用者可以僅呼叫clean生命週期的某個階段,也可以不執行clean週期,而直接執行default生命週期的某幾個階段。
2.2、clean生命週期
clean生命週期包含三個階段,主要負責清理專案,如下:
pre-clean | executes processes needed prior to the actual project cleaning |
clean | remove all files generated by the previous build |
post-clean | executes processes needed to finalize the project cleaning |
2.3、default生命週期
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 | 處理專案的主資原始檔,一般來說,是對src/main/resources目錄的內容進行變數替換等工作後,複製到專案輸出的主classpath目錄中 |
generate-resources | generate resources for inclusion in the package. |
process-resources | copy and process the resources into the destination directory, ready for packaging. |
compile | 編譯專案的主原始碼,一般來說是編譯src/main/java目錄下的JAVA檔案至專案的主classpath目錄中 |
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 | 處理專案測試資原始檔 |
generate-test-resources | create resources for testing. |
process-test-resources | copy and process the resources into the test destination directory. |
test-compile | 編譯專案的測試程式碼 |
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 | 使用合適的單元測試框架執行測試。這些測試不應該要求對程式碼進行打包或部署。 |
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 | 將編譯後的程式碼打包成可分發的格式,例如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 | 將包安裝到本地儲存庫中,以便在本地其他專案中作為依賴項使用。 |
deploy | 在整合或釋出環境中完成,將最終包複製到遠端儲存庫,以便與其他開發人員和專案共享。 |
2.4、site生命週期
siet生命週期的目的是建立和釋出專案站點,maven能夠基於POM所包含的資訊,自動生成一個友好的站點,方便團隊交流和釋出專案資訊,包含的階段如下:
pre-site | 在實際專案站點生成之前執行所需的過程 |
site | 生成專案的站點文件 |
post-site | 執行完成站點生成和準備站點部署所需的過程 |
site-deploy | 將生成的站點文件部署到指定的web伺服器 |
2.5、命令列和生命週期
從命令列執行maven任務的最主要方式就是呼叫maven的生命週期階段。需要注意的是,各個生命週期是相互獨立的,而一個生命週期的階段是有前後依賴關係的。例子如下:
- $mvn clean :該命令呼叫clean生命週期的clean階段。實際執行的階段為clean生命週期的pre-clean和clean階段。
- $mvn test:該命令呼叫default生命週期的test階段。實際呼叫的是default生命週期的validate、initialize等,直到test的所有階段。
- $mvn clean install:該命令調換用clean生命週期的clean階段和default生命週期的instal階段。
- $mvn clean deploy 該命令呼叫了clean生命週期的clean階段、default生命週期的deploy階段
3、外掛
3.1、外掛目標
maven的核心僅僅定義了抽象的生命週期,具體的任務是交由外掛完成的,外掛以獨立的形式存在。 對於外掛本身,為了能夠複用程式碼,它往往能夠完成多個任務。如maven-dependency-plugin有十多個目標,每個目標對應了一個功能,如 dependency:analyze、 dependency:tree和dependency:list。這是一種通用的寫法,冒號前面是外掛字首,後面是該外掛的目標。
3.2、外掛繫結
maven的生命週期與外掛相互繫結,用以完成實際的構建任務。具體而言,是生命週期的階段與外掛的目標相互繫結,已完成某個具體的構建任務。例如專案編譯這一任務,它對應了default生命週期的compile階段,而maven-compiler-plugin這一外掛的compile目標能夠完成該任務,因此將他們繫結。
3.2.1、 內建繫結–maven預設構建行為
為了讓使用者能夠不用任何配置就能構建maven專案,maven在核心為一些主要的生命週期預設綁定了很多外掛的目標,當用戶通過命令列呼叫生命週期階段的時候,對應的外掛目標就會執行相應的任務。 clean和site生命週期繫結的外掛目標相對簡單。
clean生命週期階段 | 外掛目標 |
---|---|
pre-clean | |
clean | maven-clean-plugin:clean |
post-clean |
default生命週期預設外掛目標繫結
deafult生命週期的階段和外掛目標的繫結關係由專案的打包理性決定(jar or 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 | 將專案輸出構件安裝到遠端倉庫 |
注意:上面只列出了擁有外掛繫結關係的階段,default生命週期還有很多其他階段,預設它們沒有繫結任何外掛
3.2.2、自定義繫結
除了內建繫結以為,使用者還能夠自己選擇獎某個外掛目標繫結到生命週期的某個階段以執行更多更特色的任務。 pom中自定義繫結外掛目標
<!-- 自動複製maven依賴包到lib目錄 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions> <!--配置執行任務-->
<execution>
<id>copy</id>
<phase>install</phase><!--繫結生命週期-->
<goals> <!--繫結外掛目標-->
<goal>copy-dependencies</goal>
</goals>
<configuration><!--配置外掛引數-->
<outputDirectory>lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
上面的配置,定義了一個id為copy的任務,利用外掛maven-dependency-plugin的copy-dependencies目標繫結到default生命週期的install階段,來實現專案依賴的jar包的自動複製。 注意: 當外掛目標被繫結到不同的生命週期階段時候,其執行順序會有生命週期階段的先後順序決定的。如果多個目標被繫結到同一個階段,他們的執行順序是由外掛宣告的先後順序決定目標的執行順序。
3.3、外掛配置
3.3.1、通過命令列配置
如 $mvn install -Dmaven.test.skip=true 的意義即跳過測試步驟。 引數-D的Java自帶的,其功能是通過命令列設定一個java系統屬性,maven簡單地重用了該引數以實現外掛引數的配置。
3.3.2、在pom中進行全域性配置
如專案編譯使用1.6版本的原始檔,生成與JVM1.6相容的位元組碼檔案:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration> <!--引數配置-->
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
3.4、利用目標字首,在命令列呼叫外掛
我們可以通過mvn命令啟用生命週期階段(例如mvn install)來執行繫結在生命週期階段的外掛目標,同時我們也可以直接呼叫外掛的目標。 呼叫方式:
mvn groupId:artifactId:version:goal
例如呼叫顯示依賴樹的外掛目標: mvn org.apache.maven.plugins:maven-dependency-plugin:2.1:tree 輸入完之後,你肯定會覺得,這命令是不是太長了????!!!!! 於是,maven提供了目標字首的概念。 maven將dependency作為 org.apache.maven.plugins:maven-dependency-plugin字首,使用
mvn dependency:tree
來呼叫外掛目標。
3.5、外掛倉庫
我們前面瞭解過依賴構件的倉庫,同樣的,外掛構件同樣也存在於maven倉庫中,但是Maven會區別對待依賴的遠端倉庫和外掛的遠端倉庫。 pom中配置一個外掛構件的遠端倉庫:(也可在setting中配置)
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Maven plugin</name>
<url>htpp://repo1.maven.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
</pluginRepositories>
配置內容與依賴的遠端倉庫配置元素相同,此處不予贅述。