原文网址:The Build Lifecycle
构建生命周期基础
Maven是以构建生命周期这个核心概念为基础。构建生命周期是指为一个工程进行项目构建和分发的过程。
为了构建一个工程,有必要去学习一系列构建Maven项目的命令,并且POM文件会确保他们能够得到想要的结果。
Maven中内置了三个构建生命周期:default,clean和site。default生命周期处理工程的部署,clean生命周期处理工程的清理,而site生命周期则负责创建工程的站点文档。
构建生命周期是由阶段组成的
三个构建生命周期都是由一系列不同的构建阶段组成,每一个构建阶段代表了生命周期的一个阶段。
例如:default生命周期是由以下的阶段组成(查看完整的生命周期阶段列表,请参考生命周期参考):
- validate – 验证该项目是否正确,所有必要的信息都是可用的
- compile – 编译工程源码
- test – 使用一个合适的单元测试框架测试编译的源代码。这些测试的代码不会被打包或部署到项目中
- package – 将编译的代码打包成它发布的格式,例如JAR
- integration-test – 如果必要的话,该命令会将工程处理并部署在一个集成测试运行的环境中
- verify – 运行任何检查以验证该包是否有效,是否符合质量标准
- install – 将工程打包安装到本地仓库中,以便本地其他项目可以进行依赖
- deploy – 在集成或发布环境中,将最终工程打包复制到远程仓库中,用于与其他开发人员和项目共享
这些生命周期阶段(包括那些这里没有展示的其他生命周期阶段)会顺序地执行来完成默认的生命周期。上述的生命周期阶段,意味着当你使用默认的生命周期时,Maven将首先验证项目,然后将编译源代码,运行那些单元测试,再打包二进制文件(例如:jar),然后再对包文件进行集成测试,再校验包文件,并将已经校验的包文件安装到本地仓库,然后在指定的环境中部署包。
要做到所有这些,你只需要调用最后一个生命阶段来执行,在这种情况下进行部署:
mvn deploy
这是因为如果你调用了一个生命阶段,它不仅执行指定的构建阶段,而且会执行指定构建阶段之前的每一个阶段。因此,执行
mvn integration-test
将会先执行该阶段之前的每一个阶段(validate, compile, package等)。
生命周期中包含了许多命令,这些将要在接下来的部分进行讨论。
需要指出的是同样的命令可以用在多模块的情况下(即包含一个或多个子项目的工程)。例如:
mvn clean install
这个命令将会遍历所有的子项目,并且运行clean命令,然后运行install命令(包含所有之前步骤的命令)
构建阶段是由插件目标组成的
即便构建阶段在生命周期中是一个特定的步骤,但是它实现这些功能的方式也可能会有所不同。这些功能是通过声明插件目标并且绑定到具体的构建阶段来实现的。
一个插件目标代表了一个特定的任务(比构建阶段更加贴切),这个任务有助于项目的建立和管理。它可能被绑定到零个或多个构建阶段。一个目标没有被绑定到任何构建阶段,可以通过直接调用来执行这个构建生命周期以外的目标。执行的顺序取决于目标和构建阶段的顺序。例如以下的这个命令:clean和package的参数是构建阶段,而dependency:copy-dependencies是一个插件目标。
mvn clean dependency:copy-dependencies package
如果这个命令被执行,clean阶段将首先执行(这意味着它将运行所有的clean生命周期前的阶段,包括clean阶段自身),然后在执行package阶段之前(及其前建立默认的生命周期阶段),将执行dependency:copy-dependencies目标。
如果一个目标被绑定到一个或多个构建阶段,这个目标将会被这些阶段所调用。
此外,构建阶段也可以绑定零个或更多的目标。如果构建阶段没有绑定目标,则该构建阶段将不执行。但如果它有一个或多个目标,它将执行所有这些绑定的目标(注:在Maven2.0.5及以上版本,多目标绑定到一个阶段是按照POM文件中定义的顺序进行执行,但是相同插件不支持多个实例。在Maven2.0.11及以上版本,相同插件的多个实例被划分成一个组,统一并有序地执行)。
使用构建生命周期来设置项目
构建生命周期的使用足够简单,但是当你为一个项目进行Maven构建时,你如何分配每个构建阶段的任务呢?
包
第一,也是最常见的方式,就是通过相同名称的POM元素来为你的项目设置包。一些有效的包的值如下:jar,war, ear和pom。如果没有指定包的值,它将默认为jar包。
每一次打包都包含一系列绑定了特殊阶段的目标。例如,打jar包将绑定以下目标,来构建默认生命周期中的各个阶段。
process-resources | resources:resources |
compile | compiler:compile |
process-test-resources | resources:testResources |
test-compile | compiler:testCompile |
test | surefire:test |
package | jar:jar |
install | install:install |
deploy | deploy:deploy |
这是一个几乎标准的绑定设置;然而,一些包的处理方式有所不同。例如,一个项目,是纯粹的元数据(包的值是POM),它仅仅绑定了install和deploy阶段(获取一个完整的打包类型的目标构建清单,请参考生命周期参考)。
值得注意的是,一些包类型即便可用,您可能还需要在你的POM文件中的build部分引入一个特殊的插件并且为那个插件定义true。举个例子,每个插件都需要引入Plexus这个插件,它提供了plexus-application和plexus-service包。
插件
向构建阶段加入目标的第二种方式是在你的项目中配置插件。插件就是向Maven提供目标的构建。此外,一个插件可能会有一个至多个的目标,插件中的每一个目标都代表了插件的一个功能。例如:编译插件拥有两个目标:compile和testCompile目标。前者会编译你的功能代码,而后者则会编译测试代码。
正如你将要在后面部分看到的那样,插件会包含一些显示目标具体绑定到哪个生命周期阶段的信息。注意,只添加一个插件自身的信息是不够的,你必须同时定义你想要运行的目标来做为你插件的一部分。
已经配置的目标将会被添加到已经绑定了包的生命周期的目标上去。如果有超过一个目标绑定到一个特殊的阶段,包中配置的目标将会被优先执行,然后再执行POM中配置的目标。注意,你可以使用元素来控制特殊目标的顺序。
例如,Modello插件默认将它的目标modello:java绑定到了generate-sources阶段(注:modello:java目标用于生成java源代码)。所以当使用Modello插件并想让它集成到一个构建阶段中来生成一个模块的代码时,你需要将下列代码添加到你POM文件元素下的中:
... <plugin> <groupId>org.codehaus.modello</groupId> <artifactId>modello-maven-plugin</artifactId> <version>1.8.1</version> <executions> <execution> <configuration> <models> <model>src/main/mdo/maven.mdo</model> </models> <version>4.0.0</version> </configuration> <goals> <goal>java</goal> </goals> </execution> </executions> </plugin> ...
你也许会疑惑为什么元素会放在这。那是为了让你能够在需要时多次运行不同配置的同一目标。也可以通过设置一个ID来实现单独运行,以便于不管是目标配置被分割还是进入一个额外的排除,你都能够控制继承或者应用程序的配置。
当设置的多个排除匹配同一个特殊阶段时,他们按照POM文件中定义的顺序执行,继承的排除设置优先执行。
现在,在modello:java这种情况下,它仅仅在generate-sources阶段起作用。但是许多目标能够在多个阶段中使用,而且他们没有一个明确的默认值。对于这些,你可以自定义阶段。比如说,你有一个目标display:time,它能够将当前的时间回显在命令行中,你想在开始测试时,让它在process-test-resources阶段运行,去显示当前时间。这就应该像这样配置:
... <plugin> <groupId>com.mycompany.example</groupId> <artifactId>display-maven-plugin</artifactId> <version>1.0</version> <executions> <execution> <phase>process-test-resources</phase> <goals> <goal>time</goal> </goals> </execution> </executions> </plugin> ...
生命周期参考
下面的列表就是default,clean和site生命周期中的所有构建阶段,他们将会按照他们定义的顺序去执行。
Clean生命周期
pre-clean | 执行一些清理前需要完成的工作 |
clean | 清理上一次构建生成的文件 |
post-clean | 执行一些清理后需要完成的工作 |
Default生命周期
validate | 校验项目是否正确以及所有重要信息是否可用 |
initialize | 初始化构建状态,例如:设置属性或者创建目录 |
generate-sources | 生成编译中包含的源代码 |
process-sources | 处理项目资源文件,例如过滤一些值 |
generate-resources | 生成包中包含的资源 |
process-resources | 复制并处理资源到目标目录,准备打包 |
compile | 编译项目中的源代码 |
process-classes | 后处理编译生成的文件,例如:对class文件进行字节码增强 |
generate-test-sources | 生成编译中包含的测试源码 |
process-test-sources | 处理测试源代码,例如:过滤一些值 |
generate-test-resources | 创建测试用的资源文件 |
process-test-resources | 复制并处理资源到目标测试目录 |
test-compile | 编译测试源码放入测试目标文件夹中 |
process-test-classes | 后处理测试编译生成的文件,例如:对class文件进行字节码增强,对Maven 2.0.5及以上有效 |
test | 使用单元测试框架运行测试。测试代码不会被打包或者部署。 |
prepare-package | 执行必要的操作,在真正打包前准备一个包。这通常会产生一个未打包、处理过版本。(Maven 2.1及以上) |
package | 接受编译好的代码,打包成可发布的格式,如:JAR |
pre-integration-test | 在集成测试执行前进行些必要的操作。这也许会涉及相关的东西,例如安装必须的环境。 |
integration-test | 处理并将包文件部署到继承测试运行的环境 |
post-integration-test | 继承测试执行之后进行的必要操作。这可能包含了清理环境操作。 |
verify | 运行一些校验去验证包是否有效,是否符合质量标准。 |
install | 安装包到本地仓库,供本地其他项目依赖使用 |
deploy | 将最终的包复制到远程仓库,供其他开发人员和Maven项目使用 |
Site生命周期
pre-site | 执行一些在生成站点之前需要完成的工作 |
site | 生成项目的站点文档 |
post-site | 执行一些在生成站点之后需要完成的工作 |
site-deploy | 将生成的站点文件发布到远程服务器上 |
<h1>内置的生命周期绑定</h1>
许多阶段都默认绑定了一些目标。对默认生命周期来说,这些绑定依赖包的值,一下就是一些目标和构建阶段的绑定。
Clean生命周期绑定
clean | clean:clean |
Default生命周期绑定 – 包 ejb / ejb3 / jar / par / rar / war
process-resources | resources:resources |
compile | compiler:compile |
process-test-resources | resources:testResources |
test-compile | compiler:testCompile |
test | surefire:test |
package | ejb:ejb or ejb3:ejb3 or jar:jar or par:par or rar:rar or war:war |
install | install:install |
deploy | deploy:deploy |
Default生命周期绑定 – 包 ear
generate-resources | ear:generate-application-xml |
process-resources | resources:resources |
package | ear:ear |
install | install:install |
deploy | deploy:deploy |
Default生命周期绑定 – 包 maven-plugin
generate-resources | plugin:descriptor |
process-resources | resources:resources |
compile | compiler:compile |
process-test-resources | resources:testResources |
test-compile | compiler:testCompile |
test | surefire:test |
package | jar:jar and plugin:addPluginArtifactMetadata |
install | install:install |
deploy | deploy:deploy |
Default生命周期绑定 – 包 pom
package | site:attach-descriptor |
install | install:install |
deploy | deploy:deploy |
Site生命周期绑定
site | site:site |
site-deploy | site:deploy |
参考
全部的Maven生命周期是由maven-core模块的components.xml文件定义的,可以参考associated documentation
在Maven 2.x中,默认生命周期绑定被包含在components.xml中,但在Maven 3.x中,他们被单独定义在default-bindings.xml描述文件中。
您可以直接从源码生成的最新文档中查看生命周期参考 和 默认生命周期插件绑定参考。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/117106.html