Maven 构建生命周期
构建生命周期的基础知识
Maven 基于一个“构建生命 周期”的中心概念,也就意味着构建和发布一个特定的工件(也就是工程)的过程已经被清晰地定义了。
有三种内置的生命周期:default,clean 和 site。default 生命周期处理处理项目部署,clean 生命周期处理项目清理,site 生命周期处理项目的站点(site)文档的创建。
实际上这些 lifecycle 只是在(比如 idea 里)对 phase 归类的时候特别有用,我们平时使用 mvn 命令的时候是无法指定这几个生命周期的。
一个构建生命周期是由多个阶段(phases)组成的
上面每个生命周期是由不同的 phase 列表组成的。一个 phase 表示一个生命周期的一个 stage(这两者有什么差别?)。
default 里 phases 的顺序大致上是是 validate
-> compile
-> test
-> package
-> verify
-> install
-> deploy
。
使用命令行
如果我们使用命令:
1 |
|
实际上到 install 为止所有的phases 都会执行,所以我们通常只要指定执行某一个生命周期的最后一个目标 phase 就行了。
如果我们使用命令:
1 |
|
maven 会先进行清理,然后再进行部署。如果这是一个多 module 的项目(即有多个子项目),则会遍历每个项目以执行 clean 和 deploy。
如果我们使用命令:
1 |
|
则执行清理、安装且跳过测试 phase。
每一个构建 phase 是由构建 goal 组成的
phase 下面还可以再细分,细分的单元就是 plugin goal。
plugin goal 其实是一个执行的任务(比 phase 更细粒度)一个 goal 可以和一个或者多个 phase 绑定,甚至在生命周期之外通过直接 invocation 运行。
1 |
|
mvn 是一级命令。
clean 和 package 是二级命令,也就是 phase。
dependency 是三级命令,也就是 plugin。
copy-dependencies差不多可以说是参数,也就是 plugin goal。
上面的命令就是执行 clean 及其前面所有的 phases 的所有 goal,单独执行 dependency 插件的 copy-dependencies goal,然后再执行 package 的所有 goal。
一个 goal 被绑定到(bound 是 bind 的过去分词形式)多个 phase,这个 goal 会被执行多遍。
设置你的项目来使用构建生命周期
如何把任务分配到构建 phases 里?
packaging
第一个方法是使用 packaging,它对应的 POM 元素是<packaging>
。它的有效值分别是:jar、war、ear 和 pom(pom 也是一个 packaging 值,证明这个项目是 purely meta data)。默认值就是 jar。
packaging 有不同的值,插件的 goal 对各个 phases 的绑定就不同。
jar 的插件绑定如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<phases>
<process-resources>
org.apache.maven.plugins:maven-resources-plugin:2.6:resources
</process-resources>
<compile>
org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
</compile>
<process-test-resources>
org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
</process-test-resources>
<test-compile>
org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile
</test-compile>
<test>
org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
</test>
<package>
org.apache.maven.plugins:maven-jar-plugin:2.4:jar
</package>
<install>
org.apache.maven.plugins:maven-install-plugin:2.4:install
</install>
<deploy>
org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
</deploy>
</phases>
其他 phases 见这个《Plugin Bindings for default Lifecycle Reference》。
如何控制构建的语言版本
1 |
|
plugins
插件是向 maven 提供 goal 的 artifact,即插件虽然自己包含很多 mojo,但它是以 artifact 的形式向外发布自己的能力(capability)的。例如,compile
插件提供两个 goal:compile
和testCompile
(注意看,没有中间的 hyphen,所以不是 phase)。
在添加插件的时候要注意,不是只是加入一个 plugin 就万事大吉了,我们需要指定我们想要在构建的时候运行的 goal。
因为 packaging 本身也含有对插件和 goal 的绑定,所以我们要当心混合使用的时候的顺序问题。我们可以使用<execution/>
来进行顺序的控制,如:
1 |
|
execution 里还可以指定 phases:
1 |
|
生命周期参考
clean 生命周期的 phases
phase | 含义 |
---|---|
pre-clean | 在实际的项目清理以前,需要被执行的处理过程(processes) |
clean | 移走前一个 build 生成的所有文件 |
post-clean | 执行所有需要用来终结项目清理的过程 |
default 的 phases
phase | 含义 |
---|---|
validate | 验证项目是正确的,且所有必须信息是可用的(实际上就是整个 pom 文件是 valid 的) |
initialize | 初始化构建状态,即设置 properties 或创建目录。也就是 properties 要在这个阶段被 inject |
generate-sources | 为任何编译中的inclusion(包含)生成源代码。 |
process-sources | 处理源代码,比如过滤某些值 |
generate-resources | 为打包的时候需要的inclusion(包含)生成资源。也就是中间资源(resources/assets)生成。 |
process-resources | 拷贝和处理资源到目标文件夹里,为打包做准备。也就是静态资源准备完毕 |
compile | 编译项目的源代码 |
process-classes | 后处理编译生成的文件,比如对 Java 类进行字节码增强。也就是 |
generate-test-sources | 为编译中的inclusion(包含)生成测试用源代码 |
process-test-sources | 处理测试源代码,比如过滤某些值 |
generate-test-resources | 为测试创建资源。 |
process-test-resources | 复制和处理资源到测试目标目录 |
test-compile | 编译测试源代码到测试目标目录 |
process-test-classes | 对测试编译的结果进行后处理,比如进行字节码增强,需要 Maven 2.0.5 和以上版本。 |
test | 用测试框架中合适的单元运行测试,这些测试不能要求类被打包和部署 |
prepare-package | 进行任何实际打包前必须的准备操作 |
package | 把编译过的远吗装进一个可发布格式,比如 JAR |
pre-integration-test | 进行集成测试前需要的活动,比如设置一个合适的环境 |
integration-test | 处理和部署一个包,如果有必要的话,部署到一个集成测试可以被运行的环境里 |
post-integration-test | 执行集成测试后需要执行的活动,比如清理环境 |
verify | 跑一些校验,来验证包是有效的,而且满足质量标准的 |
install | 把当前的包安装到本地仓库,这样可以作为其他项目的本地依赖 |
deploy | 在集成或者发布环境中执行,把包拷贝到一个远程的仓库,给其他开发者和项目共享 |
site 的 phases
phase | 含义 |
---|---|
pre-site | 执行需要在站点生成(generation)之前执行的流程 |
site | 生成项目的站点文档 |
post-site | 执行需要被用来终结站点生成的操作,来为站点部署做准备 |
site-deploy | 部署站点文档到特定的 web server 里(而不是仓库里) |