Maven:生命周期,阶段,插件,目标


106

尽管我已经使用了一段时间,但还是相对较新的开发人员,我希望巩固我的Maven基础。我的部分问题是我没有使用Ant的经验,这似乎源于许多解释。我一直在阅读和观看教程,并且不断听到相同的用语:

  • 生命周期
  • 插入
  • 目标

据我了解,生命周期似乎是最广泛的,并且由阶段,插件和/或目标组成(或由其完成)。

问题:您能否提供有关这些术语如何关联以及最常见示例的信息?

越明确越基本,越好!



谢谢@Drejc-不敢相信我在搜索中没有找到这个。我现在将通读。
杰夫·莱文

2
因此,要澄清一下,构建lifecycle = lifecycle,其中有三种类型:default,clean和site?其他解释让我认为存在第四个生命周期,称为build
杰夫·莱文


3
太宽泛?这关系到Maven的核心基础知识,并提供了一些很好而详尽的答案。没有单个Maven标签的主持人不应决定这一点。
Gerold Broser

Answers:


73

一个Maven的生命周期是一个(抽象)的概念,涵盖所有步骤(或更好:Maven的设计者决定支持所有步骤)若预计在项目开发生命周期发生。这些步骤(或阶段)在Maven术语中称为阶段

一个Maven插件是针对/供应商的容器的目标。目标中实现的代码才是真正的主力军。(Maven本身就是管理插件和执行目标)。每个插件的目标都可以分配/绑定到任何生命周期阶段。

调用时,mvn <phase> Maven将遍历所有阶段(每次)并执行绑定到给定阶段之前(包括该阶段)的任何阶段的所有目标(由插件提供)。如果某个阶段没有目标,则什么也做不了。但是该阶段还是过去了。

也就是说,您不能“插入”其他阶段到Maven的内置生命周期之一。他们已经在那里,总是!您可以按照自己的阶段来开发自己的生命周期,但这远远超出了直接使用Maven的范围。

目标也可以直接执行,在运行时您会被告知mvn目标而没有任何阶段或目标(带有换行符并在此处为便于阅读而缩短):

You must specify a valid lifecycle phase or a goal in the format

<plugin-prefix>:<goal> or

<plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>.

Available lifecycle phases are:

... see actual output or 'Maven, Introduction to the Build Lifecycle' at 'References' below ...

参考文献:

如果您想知道Maven如何知道如何在POM中没有任何目标约束的情况下进行操作default-bindings.xml,则位于的末尾有一个链接<Your Maven installation>/lib/maven-core-x.y.z.jar/META-INF/plexus/default-bindings.xml

内置生命周期的阶段(cleandefaultsite<Your Maven installation>/lib/maven-core-x.y.z.jar/META-INF/plexus/components.xml在下声明.../<component>/<role>org.apache.maven.lifecycle.Lifecycle


41

Maven:生命周期,阶段,插件,目标

稍后回答只是为了弄清楚此线程中缺少的另一个粒度级别:(目标)执行,这是Maven构建的最小单元。

因此,我们具有构建周期(基本上是针对特定总体目标的一组操作),其中包括阶段(较低的粒度,一个循环步骤),这些阶段可以调用某些插件提供的一组已配置目标。也就是说,Maven(也是)一个插件执行器,每个插件可以提供一个或多个目标。然后,您(也)决定在默认生命周期中的大多数时间中哪个目标附加到哪个阶段(没有默认值)。但是实际上,您还可以达到另一个层次:执行(具有相同目标,来自相同插件,或者具有不同目标,来自不同插件)

我准备恢复整个画面 在此处输入图片说明

实际上,这就是Maven通过其生成日志中的唯一字符串显示它(其最小的工作单元)的方式:

plugin-artifactId:plugin-version:plugin-goal (goal-execution-id) @ project-name

例如,我们将有:

[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ sample-project ---

这确实意味着(通过不同级别的粒度):

  • 在此compile阶段(不幸的是,没有提到)>
  • 我正在调用Maven编译器插件(artifactIdversion)>
  • 我正在调用其compile目标>
  • default-compile执行定义

它的独特之处在于,您确实可以将相同的目标(相同的插件)绑定到不同的阶段或相同的阶段,但是执行方式不同(即使用不同的配置)。的maven-compiler-plugin,例如,也被在使用test-compile相位(不同的相位)来编译测试代码(通过其testCompile在不同的执行目标)( default-testCompile)。您还可以在不同阶段编译(使用相同的插件和目标)一些自动生成的代码,该阶段由您在POM中指定的执行定义(可能还有不同的配置)。

默认执行是通过Maven打包绑定提供的,即开即用,即默认情况下(并强制执行配置约定),Maven在某些阶段已经调用了(标准插件的)某些目标。这些默认调用的执行ID是根据某些约定定义的。

这也解释了为什么如果您真的要覆盖Maven构建的默认行为(绑定),则需要在POM中为同一插件指定(覆盖)完全相同的执行ID。例如,您可以跳过编译,而只需定义执行maven-compiler-plugin具有相同default-compileID但绑定到不存在的阶段(或空阶段)的的执行即可。

简而言之:执行告诉Maven在哪个阶段以哪个配置执行哪个目标。

默认情况下会提供一些执行(默认绑定),这说明了为什么只有6行的maven最小pom可以做很多事情(编译,测试,打包等):在某些阶段执行标准插件的目标:组态。然后,通过配置,您可以向构建中添加内容(执行)或影响已经配置的插件的行为(在这种情况下,没有节,而仅仅是pom.xmlexecutionsconfiguration足够了)。

是的,您可以跳过构建周期(及其阶段),并直接调用(插件的)目标。想象以下情况:

mvn compiler:compile
mvn compiler:testCompile
mvn surefire:test
mvn jar:jar

(注意:您也只能在一个调用中调用内联)

在这里,我们正在编译应用程序代码,测试代码,执行测试和打包:想象一下这将是多么手动,容易出错,重复和耗时。约定优于配置有助于我们:Maven引入了构建生命周期和阶段。默认生命周期(没有名称,即默认名称)根据最佳实践和约定(Maven的口头禅)提供了一系列阶段。
如果要实现与上述相同的功能,只需运行:mvn package,它将自动编译,测试和打包您的项目。怎么样?调用插件。也就是说,阶段是有意义的且可配置的一组插件(目标)执行。为了使其更加标准化,对于每个阶段,Maven都会首先调用任何先前的阶段,因此,例如,如果您要进行测试,则可以确保首先进行编译。

ps注意,当为同一目标指定多个目标时execution,您仍将在构建日志中清楚地看到两个不同目标(因此仍然是唯一的元组)的两个不同执行(具有相同的id)。


18

感谢Sandeep Jindal和Premraj(从这里开始,Maven的目标和阶段是什么,它们之间有什么区别?)。他们的解释帮助我理解。

我在这里https://www.surasint.com/maven-life-cycle-phase-and-goal-easy-explained/创建了一些完整的代码示例和一些简单的说明。我认为这可以帮助其他人理解并可以直接尝试一些东西。

简而言之,您不应尝试一次理解所有这三个部分,首先应该了解这些组中的关系:

  • 生命周期与阶段
  • 插件与目标

1.生命周期与阶段

生命周期是按顺序收集的阶段,请参阅此处的生命周期参考。当您调用一个阶段时,它还将调用之前的所有阶段

例如,清洁生命周期分为三个阶段(预清洁,清洁,后清洁)。

mvn clean

它将称为pre-cleanclean

2.插件与目标

目标就像是Plugin中的一个动作。因此,如果plugin是一个类,目标是一种方法。

您可以这样设定目标:

mvn clean:clean

这意味着“在清理插件中调用清理目标”(这里与清理阶段无关。不要让“清理”一词使您感到困惑,它们是不一样的!请参见上面我的链接中的完整说明)

3.现在,阶段与目标之间的关系:

阶段可以(预先)链接到目标。例如,通常,清洁阶段链接到清洁目标。因此,当您调用此命令时:

mvn clean

它将调用预清洁阶段和链接到clean:clean目标的clean阶段。

它几乎与以下内容相同:

mvn pre-clean clean:clean

1
@ 2.3.恕我直言,clean:clean不是示例的最佳选择。有4个名为clean(生命周期,阶段,插件,目标)的项目可能会引起混淆,尤其是对于初学者(我记得它一开始是对我来说)。@ 3.恕我直言,动词“链接”也不是一个好选择。Maven的正式术语是“ bind ”。
Gerold Broser

@GeroldBroser。完全同意clean:clean。我已经在链接中的完整解释中进行了解释和警告。我也将警告复制到此处。之所以使用它,是因为让人们知道这个令人困惑的事物词,尤其是官方Maven文档正在使用它,并且可以清楚地解释它是一个很好的选择。是的,这也让我感到困惑。无论如何,非常感谢您的评论
Surasin Tancharoen

错字:官方的maven文档是使用并没有明确解释了它
Surasin Tancharoen

17

迟来的是另一个图

  • 生命周期为黄色矩形
  • 生命周期的阶段为蓝色矩形,带有 “可调用的”阶段,呈深蓝色(即,通常不从命令行调用带有连字符的阶段,因为它们可能没有设计成使项目处于定义明确的状态)。
  • 目标是蓝色的锭剂。所示的关联/绑定“阶段->目标”是“罐子” 打包模式之一。每个阶段都可以有目标。这当然适用于每个生命周期,尽管绑定仅针对“默认”生命周期显示。
  • 插件为灰色剪切矩形。插件提供了可以绑定到阶段的目标。

Maven生命周期,阶段,目标,插件


graphml文件(由免费的yEd编辑器编辑)可在github.com/dtonhofer/diagrams上找到
David Tonhofer

1)你究竟是“的意思是‘通知’相 ”是“ 在深蓝色 ”?每个 Maven的阶段是“通知”(虽然我宁愿把它称为可调用,因为没有代码称为通过调用阶段直接)。还是您将目标绑定到“ 可调用 ” 阶段(默认情况下)?就连这是真的,如果你看一下validateinitializeverify
Gerold Broser

2)resources:[testR|r]esources目标未绑定到生命周期中process-sourcesprocess-test-sources阶段jar
Gerold Broser

3)modello:java所述的MODELLO插件显然是域特定的。将插件的目标绑定到阶段适用于任何阶段。
Gerold Broser

@GeroldBroser根据评论进行固定。“可调用”是指可以从命令行调用它,并期望使项目保持有效状态。之间不存在有意义的区别调用调用,并调用有什么Maven的介绍使用。
David Tonhofer

12

来源,这真的是很好的教程

生命周期,生命周期阶段,插件和插件目标是Maven的核心。

  • Maven命令 mvn 只能接受生命周期阶段或插件目标作为参数。
  • Maven具有三个生命周期–默认,清理和现场。
  • 每个生命周期都由生命周期阶段组成,总共有28个阶段- 默认为21验证,...,编译,...,打包,...,安装,部署),清理3预清理,清洁,后清洁)和站点4站点前,站点,后站点,站点部署)。
  • 当使用mvn命令调用生命周期阶段时,所有先前的阶段都会依次执行。
  • 生命周期阶段本身不具备完成某些任务的能力,它们依赖于插件来执行任务。
  • 根据项目和包装的类型,Maven将各种插件目标绑定到生命周期阶段,并且目标执行委托给他们的任务。

当我们运行“在Java Project中 mvn package ”时,Maven将插件目标绑定到生命周期阶段,如下图所示。

mvn-plugins-package-goal


1
您提到的材料非常好。谢谢!
威廉·基纳

@“ Maven命令mvn只能接受生命周期阶段或插件目标作为参数。 ”不正确。它也接受选项
Gerold Broser

当我们在Java Project中运行“ mvn软件包”时,Maven将插件目标绑定到生命周期阶段是不正确的。目标绑定发生在运行之前很长时间mvn ...:在default-bindings.xml或POM中,它不是由Maven而是由人类完成的。
Gerold Broser

7

因此,如此处概述进一步解释一下

Maven构建按生命周期划分为:

  • 清洁
  • 构建(默认)
  • 现场

每个周期都分为几个阶段。例如,构建分为以下几个阶段:

  • 准备资源
  • 编译
  • 安装

阶段有目标运行之前预先或之后,例如一个阶段,:

  • 预清洁-将在清洁阶段之前执行
  • 清洁后-将在清洁阶段后执行

如果愿意,您可以将目标视为其他“插入”阶段。在此处阅读或查看@Gerolds答案以获取详细信息。


1
这个答案不是完全正确的。看我的回答
Gerold Broser

一个男孩,距离您已经回答了这个问题3年了……仍然不让它走..您赢了……现在继续前进。
德雷克

这与获胜无关。如果您以后偶然发现旧问题,答案和评论,您是否会修改?
Gerold Broser

3

LifeCycle vs Phases: Life Cycle是的集合phases。当您调用一个阶段时,它还将调用之前的所有阶段。Maven带有3个内置的构建生命周期,分别是:

  1. 清洁生命周期-这涉及清洁项目(进行新的构建和部署)
  2. 默认/构建生命周期-处理整个项目的部署
  3. 网站生命周期-处理生成项目的Java文档。 在此处输入图片说明

清洁生命周期分为三个阶段:预清洁,清洁和后清洁。默认生命周期和站点生命周期的阶段与图中所示相同。


您的最后一段是误导性的。特别是第一句话和最后一句话。目标阶段是完全不同的东西。请勿混淆它们,因为其中一些具有相同的名称。关于“ 目标是您在上图中看到的阶段。 ”:在图中没有提到单个目标。这些都是阶段。回复“ 你写的阶段名称为‘目标’时,你必须执行某些目标。 ”:虽然可以运行插件的目标明确地以通常的方式是进行积累到一定阶段mvn <phase>。在这里看到我的答案。
Gerold Broser

谢谢,我已经删除了“插件与目标”部分。我会尽快更新。
阿伦·拉伊
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.