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, 站点生成。