Maven的生命周期

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文件中的顺序执行,其中继承的执行首先运行。

生命周期详细描述

下面的表格是defaultcleansite生命周期的所有阶段,它们将按照指定的顺序执行:

  • 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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容