[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`,可以看到一些下载好的插件:
![](https://box.kancloud.cn/202f31719bb9774aebd10a8e97eb4ee1_693x333.png)
同样在maven官网,查看插件:
![](https://box.kancloud.cn/24c7fcb7c90de177ca27743c3db7cc3f_1851x891.png)
> 插件目标是插件对应的某一种功能,可以和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这一阶段,就会将源代码打包。