【问题标题】:Maven: Lifecycle vs. Phase vs. Plugin vs. Goal [closed]Maven:生命周期 vs. 阶段 vs. 插件 vs. 目标 [关闭]
【发布时间】:2014-12-23 19:52:41
【问题描述】:

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

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

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

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

越明确和基本越好!

【问题讨论】:

标签: maven maven-3 pom.xml maven-lifecycle


【解决方案1】:

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

Maven 插件目标的容器/供应商。目标中实现的代码是真正的主力。 (Maven in its core itself is just managing plugins and executing goals)。 每个插件的目标都可以分配/绑定到任何lifecycle phases

当调用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:

...

...查看实际输出或Maven, Introduction to the Build Lifecycle 在下面的References

参考文献

【讨论】:

    【解决方案2】:

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

    回答晚只是为了澄清此线程中缺少的另一个粒度级别:执行(目标),这是 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 阶段(不幸的是,仅在mvn -X ... 中提到用于调试,在REACTOR BUILD PLAN – Tasks: [...] 下)→
    • 我正在调用 Maven 编译器插件(由 artifactIdversion 指定)及其 compile 目标 →
    • executionid default-compile 定义。

    这是独一无二的,因为您确实可以将相同的目标(同一个插件)绑定到不同的阶段或绑定到同一阶段但在不同的执行中(即使用不同的配置)。例如,maven-compiler-plugintest-compile phase(不同的阶段)期间也用于在不同的执行(default-testCompile)中编译测试代码(通过其testCompile 目标)。您还可以在不同阶段编译(使用相同的插件和目标)一些自动生成的代码,这些阶段由您在 POM 中指定的执行定义(并且可能是不同的配置)。

    默认执行是通过Maven packaging bindings 开箱即用地提供的,也就是说,默认情况下(并且强制约定优于配置)Maven 已经在某些阶段调用了某些目标(标准插件的)。这些默认调用的执行id是根据certain conventions定义的。

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

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

    默认提供了一些执行(默认绑定),这就解释了为什么只有 6 行的maven minimal pom 已经可以做很多事情(编译、测试、打包等):执行目标某些阶段的标准插件:约定优于配置。然后,通过pom.xml 配置,您可以将stuff(执行)添加到构建中或影响已配置插件的行为(在这种情况下没有executions 部分,但只有configuration 将是够了)。

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

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

    (注意:您也可以在一次调用中调用内联)

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

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

    【讨论】:

      【解决方案3】:

      感谢 Sandeep Jindal 和 Premraj(来自这里 What are Maven goals and phases and what is their difference?)。他们的解释帮助我理解。

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

      简而言之,从链接中,你不应该试图同时理解所有三个,首先你应该了解这些组之间的关系:

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

      1.生命周期与阶段

      生命周期是按顺序排列的阶段的集合,请参见此处Life Cycle References。当你调用一个phase时,它也会调用它之​​前的所有phases

      例如,清洁生命周期有 3 个阶段(清洁前、清洁、清洁后)。

      mvn clean
      

      它将调用 pre-cleanclean

      2。插件与目标

      Goal 类似于 Plugin 中的操作。所以如果插件是一个类,那么目标就是一个方法。

      你可以这样称呼目标:

      mvn clean:clean
      

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

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

      阶段可以(预)链接到目标。例如,通常,清洁阶段链接到清洁目标。所以,当你调用这个命令时:

      mvn clean
      

      它将调用 pre-clean 阶段和链接到 clean:clean 目标的 clean 阶段。

      几乎是一样的:

      mvn pre-clean clean:clean
      

      【讨论】:

      • @ 2. & 3. 恕我直言,clean:clean 不是示例的最佳选择。有 4 个项目名为 clean(生命周期、阶段、插件、目标)可能会让人感到困惑,尤其是对于初学者(我记得一开始是给我的)。 @ 3. 恕我直言,动词“链接”也不是一个好的选择。官方的 Maven 术语是“bind”。
      • @GeroldBroser。完全同意 clean:clean。我已经在链接中的完整解释中解释并警告了这一点。我也会把这些警告复制到这里。我之所以使用它,是因为让人们知道这个令人困惑的词很好,尤其是官方的 maven 文档正在使用它,并且清楚地解释了它。是的,这也让我感到困惑。无论如何,非常感谢 cmets
      • 错字:maven官方文档用的,没有解释清楚
      【解决方案4】:

      迟来的另一张图

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

      【讨论】:

      • graphml 文件(使用免费的 yEd 编辑器编辑)可在github.com/dtonhofer/diagrams获取。
      • 1) “深蓝色”的““可调用”阶段“到底是什么意思? 每个 Maven 阶段都是“可调用的”(尽管我宁愿称它为invokable,因为没有代码调用 直接通过调用一个阶段)。或者您是否将具有绑定目标的阶段称为“callable”(默认情况下)?如果您查看validateinitializeverify,那也不是真的。
      • 2) resources:[testR|r]esources 目标未绑定到 process-sources or process-test-sources phases in the jar lifecycle
      • 3) Modello 插件modello:java 显然是特定于域的。将插件的目标绑定到阶段适用于任何阶段。
      • @GeroldBroser 根据 cmets 修复。 “可调用”意味着可以从命令行调用它并期望项目保持有效状态。 callinginvoking 之间没有有意义的区别,而 to callMaven Introduction 使用的。
      【解决方案5】:

      来源于this really good tutorial

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

      • Maven 命令 mvn 仅接受生命周期阶段或插件目标作为参数。
      • Maven 带有三个生命周期:默认、干净和站点。
      • 每个生命周期都由生命周期阶段组成,总共有 28 个阶段 - 默认为 21 个验证、...、编译、...、包,...,安装,部署),3 in cleanpre-clean,clean,post-clean)和4 in site 站点前、站点、站点后、站点部署)。
      • 当使用mvn 命令调用生命周期阶段时,前面的所有阶段都会依次执行。
      • 生命周期阶段本身没有能力完成任何任务,它们依赖插件来执行任务。
      • 根据项目和打包类型,Maven 将各种插件目标绑定到生命周期阶段,目标执行委托给它们的任务。

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

      【讨论】:

      • 你提到的材料很不错。谢谢!
      • @"Maven 命令 mvn 只能接受生命周期阶段或插件目标作为参数。" 不正确。它也接受options
      • "当我们在 Java 项目中运行 "mvn package" 时,Maven 将插件目标绑定到生命周期阶段" 是不正确的。目标绑定在运行 mvn ... 之前很久就发生了:在 default-bindings.xml 或 POM 中,它不是由 Maven 完成的,而是由人类完成的。
      【解决方案6】:

      所以要进一步解释一下here

      Maven 构建在生命周期中被拆分,它们是:

      • 干净
      • 构建(默认)
      • 网站

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

      • 准备资源
      • 编译
      • 安装

      阶段的目标是在 pre-post- 阶段之前运行,例如:

      • pre-clean - 将在 clean 阶段之前执行
      • post-clean - 将在 clean 阶段之后执行

      如果您愿意,您可以将目标视为额外的“插入”阶段。 阅读here 或查看@Gerolds answer 了解详情。

      【讨论】:

      • 这个答案完全不正确。见my answer
      • 哦,男孩,你已经回答了这个问题 3 年了......仍然没有放手......你赢了......现在继续前进。
      • 这与获胜无关。如果您以后偶然发现旧问题、答案和 cmets,您不会修改它们吗?
      【解决方案7】:

      生命周期与阶段: Life Cyclephases 的集合。当你调用一个阶段时,它也会调用它之​​前的所有阶段。 Maven 带有 3 个内置的构建生命周期:

      1. 清理生命周期 - 这涉及清理项目(用于新的构建和部署)
      2. 默认/构建生命周期 - 这处理项目的完整部署
      3. 站点生命周期 - 这处理生成项目的 java 文档。

      清洁生命周期有 3 个阶段:清洁前、清洁和清洁后。默认和站点生命周期的阶段如图所示。

      【讨论】:

      • 您的最后一段具有误导性。尤其是第一句和最后一句。 目标阶段是完全不同的东西。您不能混淆它们,因为其中一些具有相同的名称。关于“目标是您在上图中看到的阶段。”:图中没有提到一个目标。这些都是阶段。关于“当你必须执行某个目标时,你将阶段名称写为“目标”。”:虽然可以明确地运行插件的目标,但通常的方法是执行构建到某个目标阶段mvn &lt;phase&gt;。请在此处查看我的答案。
      • 谢谢,我已经删除了“Plugin vs Goal”部分。我会尽快更新。
      • @1. “... & 部署”——部署不是必需的,部署也是构建的一个子集。如果您查看图片,在deploy 阶段之前还有更多阶段可以停止构建。 @2。 "handles the complete deployment" – 和以前一样:默认生命周期处理一个项目的build。部署只是最后一个阶段。
      猜你喜欢
      • 2019-03-17
      • 1970-01-01
      • 2016-05-12
      • 2011-12-23
      • 2014-05-18
      • 1970-01-01
      • 1970-01-01
      • 2014-12-25
      • 1970-01-01
      相关资源
      最近更新 更多