介绍maven构建的生命周期

这篇是 https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html 的译文。

构建生命周期的基础知识

构建的生命周期是maven的最核心概念。它的意思就是构建和发布某个特定的artifact(project)的每个阶段是否清晰定义。

对想要构建一个project的开发人员来说,只需要掌握非常少的命令,就可以编译一个maven的项目,pom会保证会生成我们希望的产出结果。

有三个内置的构建周期:default,clean 和site。default周期处理项目的部署。clean周期处理项目的清理。site周期创建项目的站点文档。

构建的生命周期由阶段组成

每个生命周期都由一些不同的构建阶段组成。每个构建阶段都是生命周期的一个步骤。

例如,default生命周期由下面的阶段组成:

  • validate - 验证项目是否正确,并且所有必要的信息是否有效
  • compile - 编译项目的代码
  • test - 使用合适的单元测试框架测试源码。这些测试代码并不要求打包或者部署
  • package - 获取编译后的代码,并且把它们打成可派发的格式,比如JAR.
  • verify - 运行集成测试,以确保项目符合质量标准
  • install - 安装包到本地的repository中,以便其他项目可以依赖这个项目。
  • deploy - 在构建的结束阶段,把最终包上传到远端的repository中,以便其他的项目和开发者可以使用。

这些构建周期的各个步骤是用来顺序执行,以便完成default的生命周期。(当然其他的生命周期的步骤还没有介绍)。这就意味着,一旦使用了default生命周期,maven会首先验证项目,然后编译代码,跑单元测试,打包二进制文件,运行集成测试,验证集成测试,安装验证后的包到本地仓库,然后部署到远端仓库。

使用命令行调用

在开发环境,使用下面的命令构建和安装项目到本地仓库

mvn install

这个命令执行default生命周期中install阶段及之前的阶段(比如validate,compile,package等)。就是说,你只需要调用最后一个需要你执行的阶段就能执行这个阶段之前的命令了。

在构建环境,使用下面的命令就能清空构建发布在共享仓库中的项目。

mvn clean deploy

在多模块场景,maven进入到每个子项目并且执行clean,然后执行deploy。

一个构建的过程是由插件的目标组成

虽然一个构建过程是为构建生命周期的某个阶段负责,但是,实现这个阶段的方法有多种多样。这些方法是由绑定再这些编译阶段的插件的目标来实现的。

一个插件的目标代表一个用于构建和管理项目的任务(任务的概念比构建过程更为精细)。一个任务可以被绑定在零个或者多个构建过程上。没有被绑定在任何构建过程的目标也可以被直接调用。执行的顺序由目标和构建过程调用的顺序来定。例如,下面的命令。clean和package是构建过程,dependency:copy-dependencies是一个插件的目标。

mvn clean dependency:copy-dependencies package

执行这个命令,clean构建过程会被执行(意味着它执行clean构建过程之前的所有过程),然后dependency:copy-dependencies目标会被执行,最后,执行package构建过程(及前面所有的构建过程)。

如果一个目标绑定在一个或者多个构建阶段,这个目标会被所有构建阶段调用。

换句话说,一个构建阶段可以由零个或者多个目标绑定。如果一个构建阶段没有目标绑定,那么这个构建阶段就不会执行。但是一旦有一个或者多个目标绑定,它就会执行这些目标。

(注意:在Maven 2.0.5及之上,一个构建阶段的多个目标的执行顺序,是和这些目标在POM中声明的顺序一致的。但是,多个相同的插件是不允许的。在Maven2.0.11及以上版本,要是定义了多个相同插件,他们会被分组并且一起执行。)

一些构建阶段一般不会通过命令行进行调用

一些由复合词(pre-*, post-*, process-*)组成的构建阶段通常不会由命令行直接调用。这些构建过程连接整个构建流程,产生不被外部使用的中间结果。例如调用integration-test阶段,整个环境会停留在悬挂状态。

代码覆盖工具,例如Jacoco,执行容器插件,例如Tomcat,Cargo和Docker把目标绑定在pre-integration-test阶段,用于准备测试的容器环境。这些插件也绑定在post-integration-test阶段,用于收集覆盖率的统计,或者回收测试容器。

故障保护和代码覆盖插件绑定目标在integration-test和verify阶段。最终的结果就是在verify阶段之后生成可用的测试和代码覆盖率报告。如果integration-test由命令行调用,就不会生成任何的报告。更糟糕的是,迁移测试的容器环境就会停留在悬挂状态。Tomcat服务和Docker实例就会一直运行,maven不会自己终止。

使用构建生命周期来搭建项目

构建的生命周期是很容易使用的。但是具体当我们考虑使用maven构建一个项目的时候,如何为每个构建过程指定任务呢?

Packaging

首先,最通用的方法,通过POM中的元素为你的项目设置打包方式。一些可用的打包的值为jar, war, ear, 和pom。如果没有设置packing的值,默认为jar。

每个packaging会由一些特定的目标绑定在特定的任务中,比如,jar打包方式会绑定下面的目标在默认的生命周期中。

上图差不多就是基本的绑定设置。但是一些打包方式是不一样的设置。例如,纯元项目的打包方式(pom)只绑定了install和deploy构建阶段。

注意,除了默认的,一些额外的打包方式也是可以额外获取。你可以使用pom文件的标签来引入一个特定的插件,并且指定true。比如Plexus插件提供plexus-application和plexus-service打包方式。

Plugins

第二种把目标增加到构建阶段的方法是在你的项目中配置插件。插件就是提供目标给maven的项目。或者说,插件可以有一个或者多个目标,每个目标代表插件的一种能力。例如,Compiler插件有两个目标:compile和testCompile。前者编译你的主代码,后者编译你的测试代码。

在后面的章节你会看到,插件包含希望在什么构建阶段插入目标的信息。注意,插件自己并没有这个信息-你必须指定你想要在哪个编译阶段使用这个目标。

目标可以配置到那些已经被Packaging绑定的构建阶段中。如果多个目标绑定到一个特定阶段,执行的顺序是,先执行packaging中的目标,再执行配置文件POM配置的目标。注意,你可以通过来控制某些特定目标的执行顺序。

例如,Modello插件会将modello:java目标绑定到generate-source阶段(注意:modello:java目标会生成java代码)。所以,使用Modello插件并且让它生成代码并且将代码加入到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>
...

你也许会很好奇为什么标签存在。这样你就可以根据不同的配置文件执行多次相同的目标。每个excuteion可以配置一个唯一的ID,在继承或者应用权限阶段,你可以控制是否合并目标配置文件,还是作为一个额外的执行。

当多个executions被配置给一个单独的过程,它们会按照POM中配置的中的顺序执行。

例如,modello:java,它只在generate-source构建阶段生效。但是一些目标却会在一个或者多个构建阶段执行,并且这些目标并不强制要求按照默认阶段执行。对这些,你就需要自己来配置了。例如,你有一个目标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: 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生命周期

  • 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. For Maven 2.0.5 and above.
  • 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. (Maven 2.1 and above)
  • 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生命周期

  • 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

内置的生命周期绑定目标

一些生命周期已经绑定了一些目标。这些默认的生命周期,依赖packaging值不同有不同的目标。下面是一些构建阶段的目标:

Clean 生命周期绑定

Default 生命周期 - Packaging值为 ejb / ejb3 / jar / par / rar / war

Default 生命周期 - Packaging值为 ear

Default 生命周期 - Packaging值为 maven-plugin

Default 生命周期 - Packaging值为 pom

Site 生命周期绑定

参考

完整的Maven生命周期是在maven-core模块的components.xml文件中定义,相关查看文档

Maven2.x中,默认的生命周期绑定的目标描述是在components.xml,但在Maven3.x中,是在单独的default-bindings.xml 文件中配置的。

介绍maven构建的生命周期的更多相关文章

  1. Maven构建的生命周期

    什么是构建生命周期 构建生命周期是一组阶段的序列(sequence of phases),每个阶段定义了目标被执行的顺序.这里的阶段是生命周期的一部分.举例说明,一个典型的 Maven 构建生命周期是 ...

  2. Maven专题3——生命周期与插件

    三套生命周期 Maven有3套相互独立的生命周期,用户可以调用某个生命周期的阶段,而不会对其他生命周期产生影响. 每个生命周期包含一些有先后顺序的阶段,后面的阶段依赖于前面的阶段,意味着用户调用后面的 ...

  3. Maven整理笔记の生命周期和插件

    项目构建的生命周期,其实软件开发人员每天都在干这个事,即项目清理.初始化.编译.测试.打包.集成测试.验证.部署和站点生成等,可以说几乎所有项目的构建都可以映射到这样一个生命周期上. Maven的插件 ...

  4. 项目构建之maven篇:6.生命周期与插件

    项目生命周期 清理 初始化 编译 測试 打包 部署 三套生命周期 1.clean pre-clean 运行一些须要在clean之前完毕的工作 clean 移除全部上一次构建生成的文件 post-cle ...

  5. maven的三大生命周期

    一.Maven的生命周期 Maven的生命周期就是对所有的构建过程进行抽象和统一.包含了项目的清理.初始化.编译.测试.打包.集成测试.验证.部署和站点生成等几乎所有的构建步骤. Maven的生命周期 ...

  6. maven核心概念--生命周期

    maven有一个命令,mvn package,该命令行并没有指定一个插件目标, 而是指定了一个Maven生命周期阶段.一个阶段是在被Maven称为"构建生命周期"中的一个步骤.生命 ...

  7. 010.[转] maven的三大生命周期

    一.Maven的生命周期 Maven的生命周期就是对所有的构建过程进行抽象和统一.包含了项目的清理.初始化.编译.测试.打包.集成测试.验证.部署和站点生成等几乎所有的构建步骤. Maven的生命周期 ...

  8. maven入门-- part3 生命周期

    简介: Maven有三套相互独立的生命周期,请注意这里说的是“三套”,而且“相互独立”,这三套生命周期分别是: Clean Lifecycle 在进行真正的构建之前进行一些清理工作. Default ...

  9. Android开发之Fragment的介绍、使用及生命周期

    Fragment官网介绍-http://developer.android.com/guide/components/fragments.html 郭大神的使用实例文章:http://blog.csd ...

随机推荐

  1. 原生js简单实现双向数据绑定原理

    根据对象的访问器属性去监听对象属性的变化,访问器属性不能直接在对象中设置,而必须通过 defineProperty() 方法单独定义. 访问器属性的"值"比较特殊,读取或设置访问器 ...

  2. U盘发现器

    U盘发现器 package com.lx.io; import java.io.File; import java.io.IOException; import java.util.ArrayList ...

  3. Python判断文件是否存在的三种方法

    通常在读写文件之前,需要判断文件或目录是否存在,不然某些处理方法可能会使程序出错.所以最好在做任何操作之前,先判断文件是否存在. 这里将介绍三种判断文件或文件夹是否存在的方法,分别使用os模块.Try ...

  4. java利用接口和适配器进行完全解耦--参考《thinking in java》

    一.当使用父子类来实现以下东西时,其实是用了向上转型,这段代码的确简单了很多,复用性也很好,但是我们会发现Apply.process()和Processor类耦合过紧,其实apply.process( ...

  5. JavaScript的六种继承方式

    继承是面向对象编程中又一非常重要的概念,JavaScript支持实现继承,不支持接口继承,实现继承主要依靠原型链来实现的 原型链 首先得要明白什么是原型链,在一篇文章看懂proto和prototype ...

  6. 分享一个PHP文件上传类

    该类用于处理文件上传,可以上传一个文件,也可以上传多个文件. 包括的成员属性有: private $path = "./uploads"; //上传文件保存的路径 private ...

  7. Linux(2)文件和权限

    用户目录 位于/home/user, 称为用户目录或家目录, 表示方法: /home/user ~ 相对路径和绝对路径 绝对路径 从 / 目录开始描述的路径外绝对路径 cd /home cd /usr ...

  8. Android的ListView

    ListView ListView 是一个控件,一个在垂直滚动的列表中显示条目的一个控件,这些条目的内容来自于一个ListAdapter. 一个简单的例子 布局文件里新增ListView <Li ...

  9. 4.npm模块安装和使用(axios异步请求,lodash工具库)

    建立package.json npm init 下载包 npm install axios npm install lodash 下载包,并加到package里面 npm install axios ...

  10. JDBC连接数据库的基本步骤

    第一步:注册驱动==>:Class.forName("数据库驱动的完整名称(mysql的数据库驱动名称:com.mysql.jbdc.Driver)"); 第二步:创建一个数 ...