Build Lifecycle 生命周期
Maven是基于build生命周期的核心概念,这意味着build和distribut特定项目的过程是被清晰定义了的。对于构建项目的人来说只需要了解一小部分命令就可以构建任何Maven项目,POM会保证他们会获得所需的结果。有三个内置的生命周期:default,clean和site。
- default:处理项目的部署
- clean:处理项目的清理
- site:处理项目站点文档的构建
生命周期(Lifecycle)是由阶段(Phase)组成的
每一个构建的生命周期都由不同的构建阶段定义,其中构建阶段就代表生命周期中的一个阶段。例如default生命周期包含以下阶段:
- validate:
校验项目是否正确,所有必要的信息是否可用。 - compile:
编译项目的源代码 - test:
使用合适的单元测试框架测试编译后的源代码。这些测试不需要代码被打包或者部署 - package:
获取编译后的代码并将其打包为可分配的格式,如JAR - verify:
对集成测试的结果进行任何检查,以确保满足质量标准 - install:
将打包好的内容安装至本地仓库,用作本地其他项目的依赖 - deploy:
在构建环境中完成,将最终的包复制到远程仓库并分享给其他开发人员和项目
这些生命周期阶段(包括没有展示的其他生命周期阶段)按顺序执行以完成default生命周期。上面给定的阶段当default生命周期被使用时,Maven会首先校验这个项目然后尝试着去编译源码,运行那些测试代码然后打包二进制文件(如jar),运行针对该包的集成测试并验证,然后安装验证好的包至本地仓库,最后将安装的包部署在远程仓库。
常用的命令调用
在开发环境使用下面的命令构建并安装artifact至本地仓库:
mvn install
该命令按顺序执行default生命周期中install之前的阶段(validate,compile等)。这种情况下你只需要调用最后一个构建阶段执行即可。在生产环境中,使用下面的命令来清理构建和部署artifact到共享仓库中:
mvn clean deploy
在多模块场景中也可以使用相同的命令,Maven会遍历每一个模块的项目并执行clean然后执行deploy(包括default生命周期中的所有阶段)
阶段(Phase)是由插件的目标(Plugin Goals)组成
虽然构建的阶段负责生命周期中的一个特定步骤,但是它履行这些责任的方式可能有所不同。这是通过声明绑定到那些构建阶段的插件目标(Plugin Goals)来实现的。
插件目标(Plugin Goals)代表一个特定的任务,该任务比构建阶段(Phase)更精细,这有助于项目的构建和管理。
- Plugin Goals可以绑定到0个或多个构建Phase,未绑定到阶段的目标可以在生命周期之外直接调用执行,执行顺序取决于调用目标和构建阶段的顺序。如果一个目标被绑定到一个或多个阶段,那么在这些阶段中这个目标都会被调用。
例如 mvn clean dependency:copy-dependencies package
命令,clean和package是阶段,dependency:copy-dependencies是一个目标。如果该命令被执行则首先执行clean阶段(意味着将运行clean生命周期之前的全部阶段和clean自己周期内的阶段),然后执行dependency:copy-dependencies目标,最后执行package阶段(以及所有default声明周期中在此之前的阶段)。
- 构建Phase也可以有0个或多个Plugin Goals绑定到它,如果一个阶段没有目标绑定到它那么该阶段不会被执行;如果有一个或多个目标绑定到它,那么它将执行所有这些目标。
注意:在Maven2.0.5及以上版本中,多个目标绑定到同一个阶段的执行顺序与其在pom文件中的声明顺序相同,但是不支持一个插件的多个实例。在Maven2.0.11及以上版本中开始支持一个插件的多个实例分组在一起执行并进行排序
一些不常在命令行中调用的Phase命令
用连字符命名(pre-*, post-*, 或process-*)的阶段通常不直接在命令行中进行调用。这些阶段对构建进行排序,产生在build之外无用的中间结果。在调用integration-test时环境很可能处于挂起状态。
代码覆盖工具如Jacoco和执行容器插件如Tomcat,Cargo和Docker等将目标绑定到pre-integration-test阶段,用来准备集成测试容器环境。这些插件也将目标绑定到post-integration-test阶段来收集覆盖统计或解压缩集成测试容器。
故障安全和代码覆盖插件将目标绑定到integration-test和verify阶段。测试和覆盖率报告的网络结果将在验证(verify)阶段之后可用。如果integration-test被使用命令行调用将没有报告生成。更糟糕的是集成测试容器环境将处于挂起状态,但是Tomcat服务或Docker实例却正在运行,而Maven可能不会自己去终止它们。
设置项目以使用构建的生命周期
Packaging
第一种,最常见的方式就是设置项目的packaging变量,就是pom文件中的<packaging>属性。该变量支持的值有jar,war,ear和pom,若没有指定则默认为jar。每种packaging都包含了一系列的目标绑定到特定的阶段。以值为jar的packaging为例,下面的表格展示了其绑定到default生命周期的阶段中的目标:
阶段(Phase) | 目标(plugin:goal) |
---|---|
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 |
这几乎是标准的绑定集,然而有一些packaging在处理的时候是不同的。例如:一个纯粹的元数据(打包方式为pom)项目只绑定了install和deploy阶段(详细信息见下文-生命周期详细描述)。
注意:对于某些可用的packaging类型,你可能还需要在pom文件的<build>属性中包含特定的插件,并为那个插件指定<extensions>true</extensions>。例如:Plexus插件提供了plexus-application和plexus-service的packaging。
Plugin
第二种方式就是在项目中通过配置插件将目标添加至阶段中。插件就是为Maven提供目标的artifact。此外,一个插件可能包含一个或多个目标,其中每个目标为插件提供一种能力。例如,Complier插件有两个目标:compile和testCompile。前者编译主代码的源码,后者编译测试代码的源码。
插件可以包含将目标绑定到哪一个生命周期阶段的指示信息。不过只在插件自身添加的信息是不够的,还需要指定你希望这个目标在构建的哪一部分运行。
配置好的目标将被添加到已经通过packaging指定的绑定到生命周期的目标列表中。如果一个阶段绑定了不止一个目标,则使用的顺序是先从packaging的开始执行,然后是它们在POM文件中的配置顺序。注:可以使用 <executions>
属性去获得对于特定目标顺序的更多控制。
例如:Modello插件将 modello:java
目标绑定到default的 generate-sources
阶段(modello:java目标生成Java源代码)。所以如果要使用MyDello插件并使其从模型中生成源码并合并到构建中,就需要在POM文件选定的 <build>
中的 <plugins>
添加下面的依赖:
...
<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,以便在继承或应用程序配置期间可以控制目标的配置是合并还是转换到附加的执行中。在一个阶段中如果有多个executions被指定,那么将按其在POM文件中的顺序执行,其中继承的执行首先运行。
生命周期详细描述
下面的表格是default
,clean
和site
生命周期的所有阶段,它们将按照指定的顺序执行:
- Clean Lifecycle
阶段(Phase) | 描述信息 |
---|---|
pre-clean | 在项目实际清理之前所需执行的过程 |
clean | 删除build之前生成的所有文件 |
post-clean | 在项目清理完成后所需执行的过程 |
- Default Lifecycle
阶段(Phase) | 描述信息 |
---|---|
validate | 验证项目是正确的并且所有必要的信息都是可用的 |
initialize | 初始化生产状态,例如设置属性或创建目录 |
generate-sources | 生成编译中包含的任何源代码 |
process-sources | 处理源代码,例如过滤任何值 |
generate-resources | 生成package中包含的资源 |
process-resources | 将资源复制并处理到目标目录中,准备打包 |
compile | 编译项目的源代码 |
process-classes | 对编译生成的文件进行后处理,例如对Java类进行字节码增强 |
generate-test-sources | 生成编译中包含的任何测试源代码 |
process-test-sources | 处理测试源代码,例如过滤任何值 |
generate-test-resources | 为测试创建资源 |
process-test-resources | 将资源复制并处理到测试目标目录中 |
test-compile | 将测试源代码编译到测试目标目录中 |
process-test-classes | 对测试编译生成的文件进行后处理,例如对Java类进行字节码增强(Maven2.0.5及以上版本) |
test | 使用合适的单元测试框架运行测试,这些测试不要求对代码进行打包或部署 |
prepare-package | 在打包前进行任何必要的准备工作,这通常会有一个未打包未经过处理的包产生(Maven2.1及以上版本) |
package | 将编译后的代码打包成可分发的格式,例如JAR |
pre-integration-test | 在执行集成测试之前执行所需的操作,可能涉及诸如设置所需环境之类的事情 |
integration-test | 如果需要,处理和部署包到可以运行集成测试的环境中 |
post-integration-test | 执行集成测试后所需的操作,可能包括清理环境 |
verify | 对集成测试的结果进行任何检查,以确保满足质量标准 |
install | 将包安装到本地存储库中,作为本地其他项目的依赖项使用。 |
deploy | 在集成或发布环境中完成,将最终的包复制到远程存储库,以便与其他开发人员和项目共享。 |
- Site Lifecycle
阶段(Phase) | 描述信息 |
---|---|
pre-site | 在实际项目站点生成之前执行所需的过程 |
site | 生成项目的站点文档 |
post-site | 执行完成站点生成和准备站点部署所需的流程 |
site-deploy | 将生成的站点文档部署到指定的web服务器 |
内置生命周期绑定
有些阶段在默认情况下有目标。对于default生命周期,这些绑定依赖于packaging的值。下面是一些目标-构建阶段绑定:
Clean Lifecycle Bindings
阶段(Phase) | 目标(plugin:goal) |
---|---|
clean | clean:clean |
Default Lifecycle Bindings - Packaging ejb
/ejb3
/jar
/ par
/ rar
/ war
阶段(Phase) | 目标(plugin:goal) |
---|---|
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 Lifecycle Bindings - Packaging ear
阶段(Phase) | 目标(plugin:goal) |
---|---|
generate-resources | ear:generate-application-xml |
process-resources | resources:resources |
package | ear:ear |
install | install:install |
deploy | deploy:deploy |
Default Lifecycle Bindings - Packaging maven-plugin
阶段(Phase) | 目标(plugin:goal) |
---|---|
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 Lifecycle Bindings - Packaging pom
阶段(Phase) | 目标(plugin:goal) |
---|---|
package | |
install | install:install |
deploy | deploy:deploy |
Site Lifecycle Bindings
阶段(Phase) | 目标(plugin:goal) |
---|---|
site | site:site |
site-deploy | site-deploy |