[TOC]
# maven的生命周期和插件
一個完整的項目構建過程,通常包括清理、編譯、測試、打包、集成測試、驗證、部署等步驟,Maven 從中抽取了一套完善的、易擴展的生命周期。
## Maven生命周期
Maven包含三套內置的生命周期:
| 周期 | 作用 |
|---|---|
| clean | 清理項目 |
| default | 構建項目 |
| site | 生成項目站點文檔 |
> Maven定義了三套生命周期:clean、default、site,每個生命周期都包含了一些階段(phase)。三套生命周期相互獨立,但各個生命周期中的階段卻是有順序的,且后面的階段依賴于前面的階段。執行某個階段時,其前面的階段會依順序執行,但不會觸發另外兩套生命周期中的任何階段。比如單獨執行package,前面的編譯,測試都會自動執行。
### clean 清理項目
| 階段名稱 | 作用 |
|---|---|
| pre-clean | 執行一些清理前需要完成的工作 |
| clean | 清理上一次構建生成的文件 |
| post-clean | 執行一些清理后需要完成的工作 |
### default 構建項目(最核心)
默認(default)的生命周期,有很多,常用的階段如下:
| 階段名稱 | 作用 |
|---|---|
| compile | 編譯項目源代碼 |
| test | 使用單元測試框架運行測試。測試代碼不會被打包或者部署。 |
| package | 接受編譯好的代碼,打包成可發布的格式,如:JAR |
| install | 安裝包到本地倉庫,供本地其他項目依賴使用 |
> 這些生命周期階段(以及此處未顯示的其他生命周期階段)依次執行,以完成默認生命周期。換句話說,在生命周期里面階段是連續的,在不出錯的前提下,比如執行打包(package)時就一定是執行了測試(test)之后再執行。
### site 生成項目站點
| 階段名稱 | 作用 |
|---|---|
| pre-site | 執行一些在生成站點之前需要完成的工作 |
| site | 生成項目站點文檔|
| post-site | 執行一些在生成站點之后需要完成的工作 |
| site-deploy | 將生成的站點文件發布到遠程服務器上 |
> 以連字符(pre-*,post-*)命名的階段通常不會從命令行直接調用。這些階段對構建進行排序,生成在構建之外無用的中間結果,只起到了中間階段的作用,換句話說只是一個過客。
## 插件
Maven的生命周期是抽象的,其中的具體任務,都交由插件來完成。Maven為大多數構建任務編寫并綁定了默認的插件,如針對編譯的插件:maven-compiler-plugin。用戶也可自行配置或編寫插件。
Maven的核心文件很小,主要的任務都是由插件來完成。定位到:`%本地倉庫%\org\apache\maven\plugins`,可以看到一些下載好的插件:

同樣在maven官網,查看插件:

> 插件目標是插件對應的某一種功能,可以和maven生命周期的階段綁定。
### 默認綁定
| 生命周期階段 | 插件目標 |
|---|---|
|process-resources|maven-resource-plugin:resources|
|compile|maven-compiler-plugin:compile|
|process-test-resource|maven-resource-plugin:testResources|
|test-compile|maven-compiler-plugin:testCompile|
|test|maven-surefire-plugin:test|
|package| maven-jar-plugin:jar|
|install|maven-install-plugin:install|
|deploy|maven-deploy-plugin:deploy|
### 自定義綁定
用戶可以自己配置某個插件的某個目標綁定生命周期的某個階段,讓maven在構建項目時執行更多富有特色的任務。
```
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dodoke</groupId>
<artifactId>j2se</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>j2se</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>attach-sources</id>
<!-- 要綁定到的生命周期的階段 -->
<phase>package</phase>
<goals>
<!-- 要綁定的插件的目標 -->
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
```
在 POM 的 build 元素下的 plugins 子元素中聲明插件的使用,除了插件坐標聲明外,還有插件執行配置,executions 下每個 execution 子元素可以用來配置執行一個任務。該例中配置了一個 id 為 arrach-sources 的任務,通過 phase 配置綁定的周期階段 package,再通過 goals 配置指定要執行的插件目標。至此自定義插件綁定完成,運行 clean package 就能看到如下輸出:
`[INFO] Building jar: D:\work_maven\j2se\target\j2se-0.0.1-SNAPSHOT-sources.jar`
> 也就是說只要執行的mvn命令所屬的聲明周期包括package這一階段,就會將源代碼打包。