Maven使用POM描述项目,将其建模成一些名词。POM记录了一个项目的定义:项目包含什么?需要怎样的打包类型?是否包含一个父项目?它的依赖是什么?我们已经在前面的章节展示了如何描述一个项目,但还没有介绍一种允许Maven针对这些对象进行操作的机制。在Maven中这些“动词”是由Maven插件包装的一些目标,它们绑定到一个构建生命周期的阶段中。一个Maven生命周期包含了一些有序的命名阶段:prepare-resources,compile,package,和install以及其它。有个阶段抽象了编译过程,有个阶段抽象了打包过程。而那些pre-和post-阶段可以用来注册一些必须在某些特定阶段之前或之后运行的目标。当你让Maven构建一个项目的时候,你其实是让它一步步通过那些预定义的有序的阶段,并且运行所有注册到某个特定阶段的目标。
一个构建生命周期是一组精心组织的有序的阶段,它的存在能使所有注册的目标变得有序运行。这些目标根据项目的打包类型被选择并绑定。Maven中有三种标准的生命周期:清理(clean),默认(default)(有时候也称为构建),和站点(site)。本章,我们将学习Maven如何将目标绑定到生命周期,生命周期如何自定义。你同时也会学到默认生命周期阶段的知识。
第一个你将感兴趣的生命周期是Maven中最简单的生命周期。运行mvn clean将调用清理生命周期,它包含了三个生命周期阶段:
-
pre-clean -
clean -
post-clean
在清理生命周期中最有意思的阶段是clean阶段。Clean插件的clean目标(clean:clean)被绑定到清理生命周期中的clean阶段。目标clean:clean通过删除构建目录删除整个构建的输出。如果你没有自定义构建目录位置,那么构建目录就是定义在超级POM中的/data/hudson-temporal-data/hudson-orchestrator-home/workspace/Book-To-Production/content-zh/target。当你运行clean:clean目标的时候你并不是直接运行mvn
clean:clean,你可以通过执行清理生命周期的clean阶段运行该目标。运行clean阶段能让Maven有机会执行其它可能被绑定到pre-clean阶段的目标。
例如,假设你想要在pre-clean的时候触发一个antrun:run目标任务来输出一个通知,或者需要在项目构建目录被删除之前将其归档。简单的运行clean:clean目标不会完整的执行该生命周期,但是指定clean阶段就能使用clean生命周期,并且逐个的经过生命周期阶段,直到到达clean阶段。Example 10.1, “在pre-clean阶段触发一个目标”展示了一个样例,在它的构建配置中,绑定了antrun:run至pre-clean阶段,输出一个警告告诉用户项目构件即将被删除。该例中,antrun:run目标被用来执行一些随意的Ant命令来检查项目的构件。如果项目的构件将要被删除,它会打印该信息至屏幕。
Example 10.1. 在pre-clean阶段触发一个目标
<project>
...
<build>
<plugins>... <plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>file-exists</id>
<phase>pre-clean</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<!-- adds the ant-contrib tasks (if/then/else used below) -->
<taskdef resource="net/sf/antcontrib/antcontrib.properties" />
<available
file="/data/hudson-temporal-data/hudson-orchestrator-home/workspace/Book-To-Production/content-zh/target/book.jar"
property="file.exists" value="true" />
<if>
<not>
<isset property="file.exists" />
</not>
<then>
<echo>No
book.jar to
delete</echo>
</then>
<else>
<echo>Deleting
book.jar</echo>
</else>
</if>
</tasks>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>1.0b2</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
在带有如上构建配置的项目中运行mvn clean会生成如下的输出:
[INFO] Scanning for projects...
[INFO] ----------------------------------------------------------------------
[INFO] Building Your Project
[INFO] task-segment: [clean]
[INFO] ----------------------------------------------------------------------
[INFO] [antrun:run {execution: file-exists}]
[INFO] Executing tasks
[echo] Deleting your-project-1.0-SNAPSHOT.jar
[INFO] Executed tasks
[INFO] [clean:clean]
[INFO] Deleting directory ~/corp/your-project/target
[INFO] Deleting directory ~/corp/your-project/target/classes
[INFO] Deleting directory ~/corp/your-project/target/test-classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Wed Nov 08 11:46:26 CST 2006
[INFO] Final Memory: 2M/5M
[INFO] ------------------------------------------------------------------------
除了在pre-clean阶段配置Maven去运行一个目标,你也可以自定义Clean插件去删除构建输出目录以外的文件。你可以配置该插件去删除那些在fileSet中指定的文件。下面的样例配置了Clean插件,使用标准的Ant文件通配符:*和**,删除所有target-other/目录中的.class文件。
Example 10.2. 自定义Clean插件的行为
<project>
<modelVersion>4.0.0</modelVersion>
...
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<configuration>
<filesets>
<fileset>
<directory>target-other</directory>
<includes>
<include>*.class</include>
</includes>
</fileset>
</filesets>
</configuration>
</plugin>
</plugins>
</build>
</project>大部分Maven用户将会对默认生命周期十分熟悉。它是一个软件应用程序构建过程的总体模型。第一个阶段是validate,最后一个阶段是deploy。这些默认Maven生命周期的阶段如Table 10.1, “Maven默认生命周期阶段”所示:
Table 10.1. Maven默认生命周期阶段
| 生命周期阶段 | 描述 |
|---|---|
| validate | 验证项目是否正确,以及所有为了完整构建必要的信息是否可用 |
| generate-sources | 生成所有需要包含在编译过程中的源代码 |
| process-sources | 处理源代码,比如过滤一些值 |
| generate-resources | 生成所有需要包含在打包过程中的资源文件 |
| process-resources | 复制并处理资源文件至目标目录,准备打包 |
| compile | 编译项目的源代码 |
| process-classes | 后处理编译生成的文件,例如对Java类进行字节码增强(bytecode enhancement) |
| generate-test-sources | 生成所有包含在测试编译过程中的测试源码 |
| process-test-sources | 处理测试源码,比如过滤一些值 |
| generate-test-resources | 生成测试需要的资源文件 |
| process-test-resources | 复制并处理测试资源文件至测试目标目录 |
| test-compile | 编译测试源码至测试目标目录 |
| test | 使用合适的单元测试框架运行测试。这些测试应该不需要代码被打包或发布 |
| prepare-package | 在真正的打包之前,执行一些准备打包必要的操作。这通常会产生一个包的展开的处理过的版本(将会在Maven 2.1+中实现) |
| package | 将编译好的代码打包成可分发的格式,如JAR,WAR,或者EAR |
| pre-integration-test | 执行一些在集成测试运行之前需要的动作。如建立集成测试需要的环境 |
| integration-test | 如果有必要的话,处理包并发布至集成测试可以运行的环境 |
| post-integration-test | 执行一些在集成测试运行之后需要的动作。如清理集成测试环境。 |
| verify | 执行所有检查,验证包是有效的,符合质量规范 |
| install | 安装包至本地仓库,以备本地的其它项目作为依赖使用 |
| deploy | 复制最终的包至远程仓库,共享给其它开发人员和项目(通常和一次正式的发布相关) |
Maven不仅仅能从一个项目构建软件构件,它还能为一个或者一组项目生成项目文档和报告。项目文档和站点生成有一个专有的生命周期,它包含了四个阶段:
-
pre-site
-
site
-
post-site
-
site-deploy
默认绑定到站点生命周期的目标是:
-
site - site:site
-
site-deploy -site:deploy
打包类型通常不更改此生命周期,因为打包类型主要和构件创建有关,和站点生成没有太大的关系。Site插件触发Doxia执行文档生成,以及执行其它报告生成插件。你可以通过运行如下命令从一个Maven项目生成一个站点:
$ mvn site
有关更多的Maven站点生成信息,查看Chapter 15, 站点生成。

