文中加粗显示的英文是在官方文档中出现的术语,我使用的相应术语的中文翻译,不能保证十分准确,严谨起见,在使用中文直译的术语后,使用了对应的英文属于。由于博主水平有限,非常欢迎大家能够批评指正。
一 构建声明周期基础知识
我们在日常中,经常提及Maven(美式发音/?me?vn/ )中的一个专业术语:声明周期 Lifecycle,然而,它在官方文档中的名称却是:Build Lifecycle (直译为,构建生命周期)。”Build"一词,我个人更倾向于把它理解为操作或者处理,声明周期即是一个过程,就像人会生、老、病、死的一个明确被定义的过程。之所以这样理解Build,是为了和默认声明周期过程中的构建区别开来,这里的构建是把一个项目从无到有创建出来。构建声明周期就是处理项目的过程。为了方便描述和避免歧义,下文中的术语都是使用声明周期。
声明周期是Maven的核心概念,它清楚地定义了一个项目被构建(创建)和发布的过程。
Maven中内置了三套生命周期(依据不同的目的,定义了三种处理项目的过程):
default lifecycle 负责项目的构建、发布clean lifecycle 负责清理项目site lifecycle 负责生成项目站点,即API文档信息网站
二 生命周期是由阶段组成的
Each of these build lifecycles is defined by a different list of build phases, wherein a build phase represents a stage in the lifecycle.
每个声明周期由若干不同的阶段(Phase( 美 /fe?z/ )组成。阶段代表了生命周期的特殊步骤。
例如,default lifecycle 由下列阶段组成(这里列出了部分阶段,完整阶段下文会介绍)
validate 验证项目是正确的,所有必要的信息都是可用的compile 编译项目源代码test 使用单元测试框架测试编译后的源代码package 获取已编译的代码,并将其打包为可发行的格式,例如JAR。verify 获取已编译的代码,并将其打包为可发行的格式,例如JAR。install 将包安装到本地仓库,供本地项目使用 将包发布到远程仓库(remote repository),方便其他开发人员和项目共享。
These lifecycle phases are executed sequentially.
生命周期阶段是按(在生命周期中定义的)顺序执行的。例如,在执行package阶段时,会先按顺序执行validate、compile、test阶段,最后执行package阶段。注意,上文提及的只是部分主要阶段,compile和test阶段之间存在着其他阶段,也是按照其在default lifecycle中定义的顺序执行的。
三 阶段是由插件目标组成的
However, even though a build phase is responsible for a specific step in the build lifecycle, the manner in which it carries out those responsibilities may vary. And this is done by declaring the plugin goals bound to those build phases.
阶段对生命周期的特殊步骤负责,它履行职责的方式可能不同,取决于绑定到阶段的插件目标。简而言之,阶段的执行依赖于插件目标。(plugin goal)
例如:compile阶段履行编译职责,依赖于插件目标 compiler:compile ,这里compiler代表了插件maven-compiler-plugin (本质是maven-compiler-plugin-3.1.jar),compile表示(插件)目标(本质上应该是要选择类中的一个方法执行,具体还有看源码,主要就是选择一个模块执行)。
A plugin goal represents a specific task (finer than a build phase) which contributes to the building and managing of a project. It may be bound to zero or more build phases. A goal not bound to any build phase could be executed outside of the build lifecycle by direct invocation.
Moreover, if a goal is bound to one or more build phases, that goal will be called in all those phases.
Furthermore, a build phase can also have zero or more goals bound to it. If a build phase has no goals bound to it, that build phase will not execute. But if it has one or more goals bound to it, it will execute all those goals.
内容较多,挑选主要内容翻译。
1. 插件目标代表明确的任务。
例如:jar:jar 把编译的二进制class文件打包,格式JAR;install:install 把打包文件安装到本地仓库等等。
2. 一个生命周期阶段可以绑定零或多个插件目标。如果,某生命周期阶段没有绑定插件目标(或者说绑定零个插件目标),它将不会执行。绑定多个按绑定的先后顺序执行。(后文会详细介绍阶段如何绑定目标,及执行顺序)
例如: 打包方式(packaging)为pom 时,生命周期阶段package 没有绑定任何插件目标,因此不会执行。打包方式为pom时主要用于父项目,统一管理依赖。不进行打包,也是可以理解的。(不熟悉,没关系,后文会详细介绍打包方式)
打包方式为maven-plugin 时,生命周期阶段package 绑定了多个(实际为2个)插件目标jar:jar 和 plugin:addPluginArtifactMetadata
3. 一个插件目标可以绑定到零个或者多个生命周期阶段上。如果某插件目标没有绑定到生命周期阶段上(即绑定到零个生命周期阶段),它执行任务的方式时直接调用。
例如:插件目标install:install ,它被绑定到了install 阶段,在命令行中输入mvn install ,首先执行default lifecycle 中install之前的所有生命周期阶段,最后执行install阶段,此时,插件目标install:install 执行任务。假设,还有其他插件目标绑定到install阶段,也会被调用来执行相应的任务。
有些插件目标,如,tomcat7:run 没有绑定到任务生命周期阶段,它想要执行任务,可以通过直接调用(direct invocation),在命令行中输入mvn tomcat7:run ,就可以执行任务。
另外,在命令行输入install:install ,只会执行安装包到本地仓库的任务。如果,install 阶段之前的所有生命周期阶段没有执行,此时会报错,因为没有install之前的阶段履行职责,可能根本不存在jar包。
简言之,插件目标执行任务,可以直接调用。也可以由阶段调用。
四 生命周期及履行职责
下面列出了default、clean和site生命周期的所有阶段,它们按照在下表中定义的顺序执行的。当执行某个阶段,先执行其之前的所有阶段,然后执行该阶段。用连字符命名的阶段(pre-*、post-或process-)通常不会直接从命令行调用。它们履行的职责主要是生成一些中间产物等等
Clean Lifecycle
Phase | Description |
---|
pre-clean | execute processes needed prior to the actual project cleaning | clean | remove all files generated by the previous build | post-clean | execute processes needed to finalize the project cleaning |
Default Lifecycle
Phase | Description |
---|
validate | validate the project is correct and all necessary information is available. | initialize | initialize build state, e.g. set properties or create directories. | generate-sources | generate any source code for inclusion in compilation. | process-sources | process the source code, for example to filter any values. | generate-resources | generate resources for inclusion in the package. | process-resources | copy and process the resources into the destination directory, ready for packaging. | compile | compile the source code of the project. | process-classes | post-process the generated files from compilation, for example to do bytecode enhancement on Java classes. | generate-test-sources | generate any test source code for inclusion in compilation. | process-test-sources | process the test source code, for example to filter any values. | generate-test-resources | create resources for testing. | process-test-resources | copy and process the resources into the test destination directory. | test-compile | compile the test source code into the test destination directory | process-test-classes | post-process the generated files from test compilation, for example to do bytecode enhancement on Java classes. | test | run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed. | prepare-package | perform any operations necessary to prepare a package before the actual packaging. This often results in an unpacked, processed version of the package. | package | take the compiled code and package it in its distributable format, such as a JAR. | pre-integration-test | perform actions required before integration tests are executed. This may involve things such as setting up the required environment. | integration-test | process and deploy the package if necessary into an environment where integration tests can be run. | post-integration-test | perform actions required after integration tests have been executed. This may including cleaning up the environment. | verify | run any checks to verify the package is valid and meets quality criteria. | install | install the package into the local repository, for use as a dependency in other projects locally. | deploy | done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects. |
Site Lifecycle
Phase | Description |
---|
pre-site | execute processes needed prior to the actual project site generation | site | generate the project's site documentation | post-site | execute processes needed to finalize the site generation, and to prepare for site deployment | site-deploy | deploy the generated site documentation to the specified web server |
四 如何为生命周期阶段赋予或绑定插件目标
主要有两种方式,第一种方式,使用Maven内置的绑定。Maven根据不同的打包方式,为某些阶段默认绑定插件目标。由于其打包生成的目标包不同,因此阶段和阶段绑定的插件目标也存在差异。第二种方式,通过配置pom.xml文件,为阶段绑定插件目标。如此,阶段可能包含多个插件目标,其执行顺序为,先执行maven内置的为阶段绑定的目标(如果该阶段绑定了插件目标的话),然后按照你在pom文件中配置的插件目标的顺序依次执行(如果你为该阶段配置了多个插件目标的话)
Packaging
通过POM元素<packaging> 设置打包方式,有效值有:jar 、war 、ear 、pom 。如果没有设置该值,默认值为jar 。
每种打包方式包含的阶段以及阶段绑定的插件目标存在些许差异。
默认声明周期-打包方式 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 |
Clean Lifecycle Bindings
Phase | plugin:goal |
---|
clean | clean:clean |
Site Lifecycle Bindings
Phase | plugin:goal |
---|
site | site:site | site-deploy | site:deploy |
|