Maven构建生命周期
以下内容来自官网翻译,红色字是我补充:https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#
构建生命周期简介
目录
构建生命周期基础
Maven基于构建生命周期的核心概念。这意味着明确定义了构建和分发特定工件(项目)的过程。
对于构建项目的人来说,这意味着只需要学习一小组命令来构建任何Maven项目,POM将确保他们获得所需的结果。
有三个内置的构建生命周期:default, clean and site。在default
生命周期处理你的项目部署中,clean
生命周期处理项目的清洗,而site
生命周期处理项目的网站文件的创建。
这些构建生命周期中的每一个都由不同的构建阶段列表定义,其中构建阶段表示生命周期中的阶段。
例如,默认生命周期包括以下阶段(注意:这里是简化的阶段。有关生命周期阶段的完整列表,请参阅生命周期参考):
validate
- 验证项目是否正确,并提供所有必要信息compile
- 编译项目的源代码test
- 使用合适的单元测试框架测试编译的源代码。这些测试不应要求打包或部署代码package
- 获取已编译的代码并将其打包为可分发的格式,例如JAR。verify
- 对集成测试结果进行任何检查,以确保满足质量标准install
- 将软件包安装到本地存储库中,以便在本地用作其他项目的依赖项deploy
- 在构建环境中完成,将最终包复制到远程存储库以与其他开发人员和项目共享。
这些生命周期阶段(以及此处未显示的其他生命周期阶段)按顺序执行以完成default
生命周期。鉴于上面的生命周期阶段,这意味着当使用默认生命周期时,Maven将首先验证项目,然后将尝试编译源代码,针对测试运行,打包二进制文件(例如jar),对其运行集成测试包,验证集成测试,将经过验证的软件包安装到本地存储库,然后将已安装的软件包部署到远程存储库。
[顶]。
在开发环境中,使用以下调用在本地存储库中构建和安装工件。
mvn install
此命令按顺序执行每个默认生命周期阶段(validate
,compile
,package
等),在执行之前install
。在这种情况下,您只需要调用要执行的最后一个构建阶段install
:
在构建环境中,使用以下调用来干净地构建工件并将其部署到共享存储库中。
mvn clean deploy
可以在多模块场景(即具有一个或多个子项目的项目)中使用相同的命令。Maven遍历每个子项目并执行clean
,然后执行deploy
(包括所有先前的构建阶段步骤)。
注意:在我们开发阶段,有一些生命周期的阶段,比如验证(validate)这些,基本很少用到。只要使用关键的几个基本能满足需求。
[顶]。
但是,即使构建阶段负责构建生命周期中的特定步骤,它执行这些职责的方式也可能不同。这是通过声明绑定到那些构建阶段的插件目标来完成的。
插件目标表示特定任务(比构建阶段更精细),这有助于构建和管理项目。它可能绑定到零个或多个构建阶段。未绑定到任何构建阶段的目标可以通过直接调用在构建生命周期之外执行。执行顺序取决于调用目标和构建阶段的顺序。例如,请考虑以下命令。在clean
和package
参数是构建阶段,而dependency:copy-dependencies
为(的插件)的目标。
mvn clean dependency:copy-dependencies package
如果要执行此操作,则首先执行clean
阶段(意味着它将运行清洁生命周期的所有前几个阶段,再加上clean
阶段本身),然后执行dependency:copy-dependencies
目标,然后再执行package
阶段(及其之前的所有构建阶段)默认生命周期)。
此外,如果目标绑定到一个或多个构建阶段,则将在所有这些阶段调用该目标。
此外,构建阶段也可以具有零个或多个绑定目标。如果构建阶段没有绑定目标,则不会执行该构建阶段。但如果它有一个或多个与之绑定的目标,它将执行所有这些目标
(注意:在Maven 2.0.5及更高版本中,绑定到阶段的多个目标的执行顺序与它们在POM中声明的顺序相同,但不支持同一插件的多个实例。同一插件的多个实例被分组一起执行并在Maven 2.0.11及更高版本中订购)。
[顶]。
用连字符(pre-*
,post-*
或process-*
)命名的阶段通常不直接从命令行调用。这些阶段对构建进行排序,产生在构建之外无用的中间结果。在调用的情况下integration-test
,环境可以处于挂起状态。
代码覆盖工具(如Jacoco)和执行容器插件(如Tomcat,Cargo和Docker)将目标绑定pre-integration-test
到准备集成测试容器环境的阶段。这些插件还将目标绑定到post-integration-test
阶段以收集覆盖率统计信息或停用集成测试容器。
故障安全和代码覆盖插件绑定目标,integration-test
和verify
阶段。最终结果是测试和覆盖率报告在verify
阶段之后可用。如果integration-test
要从命令行调用,则不会生成任何报告。更糟糕的是集成测试容器环境处于挂起状态; Tomcat Web服务器或Docker实例保持运行,Maven甚至可能不会自行终止。
[顶]。
设置项目以使用构建生命周期
构建生命周期很简单,但是当您为项目构建Maven构建时,如何为每个构建阶段分配任务?
第一种也是最常见的方法是通过同名的POM元素为项目设置包装<packaging>
。一些有效的包装价值的是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
阶段(对于某些打包类型的目标到构建阶段绑定的完整列表,请参阅生命周期参考)。
请注意,对于某些可用的打包类型,您可能还需要在<build>
POM 的部分中包含特定插件并<extensions>true</extensions>
为该插件指定。需要此插件的一个例子是丛插件,它提供了一个plexus-application
与plexus-service
包装。
[顶]。
向阶段添加目标的第二种方法是在项目中配置插件。插件是为Maven提供目标的工件。此外,插件可以具有一个或多个目标,其中每个目标表示该插件的能力。例如,Compiler插件有两个目标:compile
和testCompile
。前者编译主代码的源代码,后者编译测试代码的源代码。
正如您将在后面的部分中看到的,插件可以包含指示将目标绑定到哪个生命周期阶段的信息。请注意,添加插件本身并不足够 - 您还必须指定要在构建过程中运行的目标。
已配置的目标将添加到已从所选包装绑定到生命周期的目标中。如果多个目标绑定到特定阶段,则使用的顺序是首先执行打包中的目标,然后执行POM中配置的目标。请注意,您可以使用该<executions>
元素来更好地控制特定目标的顺序。
例如,Modello插件默认绑定modello:java
到generate-sources
阶段的modello:java
目标(注意:目标生成Java源代码)。因此,要使用Modello插件并让它从模型生成源并将其合并到构建中,您可以在以下<plugins>
部分中将以下内容添加到POM <build>
:
... <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> ...
你可能想知道为什么那个<executions>
元素存在。这样,如果需要,您可以使用不同的配置多次运行相同的目标。单独执行也可以获得一个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
生命周期,这是在放弃了指定的一个点的顺序执行。
清洁生命周期
阶段 | 描述 |
---|---|
pre-clean | 在实际项目清理之前执行所需的过程 |
clean | 删除上一个版本生成的所有文件 |
post-clean | 执行完成项目清理所需的过程 |
默认生命周期
阶段 | 描述 |
---|---|
validate | 验证项目是否正确,并提供所有必要信息。 |
initialize | 初始化构建状态,例如设置属性或创建目录。 |
generate-sources | 生成任何包含在编译中的源代码。 |
process-sources | 处理源代码,例如过滤任何值。 |
generate-resources | 生成包含在包中的资源。 |
process-resources | 将资源复制并处理到目标目录,准备打包。 |
compile | 编译项目的源代码。 |
process-classes | 从编译中对生成的文件进行后处理,例如对Java类进行字节码增强。 |
generate-test-sources | 生成任何测试源代码以包含在编译中。 |
process-test-sources | 处理测试源代码,例如过滤任何值。 |
generate-test-resources | 创建用于测试的资源。 |
process-test-resources | 将资源复制并处理到测试目标目录中。 |
test-compile | 将测试源代码编译到测试目标目录中 |
process-test-classes | 从测试编译中对生成的文件进行后处理,例如对Java类进行字节码增强。适用于Maven 2.0.5及以上版本。 |
test | 使用合适的单元测试框架运行测试。这些测试不应要求打包或部署代码。 |
prepare-package | 在实际包装之前执行准备包装所需的任何操作。这通常会导致包的解包,处理版本。(Maven 2.1及以上) |
package | 获取已编译的代码并将其打包为可分发的格式,例如JAR。 |
pre-integration-test | 在执行集成测试之前执行所需的操作。这可能涉及诸如设置所需环境之类的事情。 |
integration-test | 如有必要,将程序包处理并部署到可以运行集成测试的环境中。 |
post-integration-test | 执行集成测试后执行所需的操作。这可能包括清理环境。 |
verify | 运行任何检查以验证包是否有效并符合质量标准。 |
install | 将软件包安装到本地存储库中,以便在本地用作其他项目的依赖项。 |
deploy | 在集成或发布环境中完成,将最终包复制到远程存储库以与其他开发人员和项目共享。 |
网站生命周期
阶段 | 描述 |
---|---|
pre-site | 在实际项目站点生成之前执行所需的过程 |
site | 生成项目的站点文档 |
post-site | 执行完成站点生成所需的流程,并准备站点部署 |
site-deploy | 将生成的站点文档部署到指定的Web服务器 |
[顶]。
内置生命周期绑定
默认情况下,某些阶段的目标与它们绑定。对于默认生命周期,这些绑定取决于包装值。以下是一些构建阶段绑定的目标。
阶段 | 插件:目标 |
---|---|
clean | clean:clean |
默认生命周期绑定 - 包装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 或 ejb3:ejb3 或 jar:jar 或 par:par 或 rar:rar 或 war:war |
install | install:install |
deploy | deploy:deploy |
阶段 | 插件:目标 |
---|---|
generate-resources | ear:generate-application-xml |
process-resources | resources:resources |
package | ear:ear |
install | install:install |
deploy | deploy:deploy |
相 | 插件:目标 |
---|---|
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 和 plugin:addPluginArtifactMetadata |
install | install:install |
deploy | deploy:deploy |
相 | 插件:目标 |
---|---|
package | |
install | install:install |
deploy | deploy:deploy |
相 | 插件:目标 |
---|---|
site | site:site |
site-deploy | site:deploy |
完整的Maven生命周期由模块中的components.xml
文件定义maven-core
,并提供相关文档以供参考。
默认生命周期绑定在单独的default-bindings.xml
描述符中定义。
有关直接从源代码获取的最新文档,请参阅生命周期参考和插件绑定以获取默认生命周期参考。