什么是 Maven 目标和阶段,它们有什么区别?

Posted

技术标签:

【中文标题】什么是 Maven 目标和阶段,它们有什么区别?【英文标题】:What are Maven goals and phases and what is their difference? 【发布时间】:2013-04-18 19:37:56 【问题描述】:

Maven 目标和阶段之间有什么区别/关系?它们是如何相互关联的?

【问题讨论】:

在Maven: Lifecycle vs. Phase vs. Plugin vs. Goal 中询问和answered(再一次)。 Maven: Lifecycle vs. Phase vs. Plugin vs. Goal的可能重复 【参考方案1】:

目标是分阶段执行的,这有助于确定执行目标的顺序。对此最好的理解是查看default Maven lifecycle bindings,它显示了默认情况下哪些目标在哪些阶段运行。 compile 阶段目标将始终在test 阶段目标之前执行,而test 阶段目标将始终在package 阶段目标之前执行,依此类推。

在执行 Maven 时可以指定目标或阶段这一事实加剧了部分混淆。如果您指定一个阶段,那么 Maven 将按顺序运行所有阶段,直到您指定的阶段(例如,如果您指定包,它将首先运行通过编译阶段,然后是测试阶段,最后是包阶段),并且对于每个阶段,它将运行与该阶段相关的所有目标。

当您在 Maven 构建文件中创建插件执行并且您只指定目标时,它将将该目标绑定到给定的默认阶段。例如,jaxb:xjc 目标默认绑定到generate-resources 阶段。但是,当您指定执行时,您也可以明确指定该目标的阶段。

如果您在执行 Maven 时指定了一个目标,那么它将运行该目标并且只运行该目标。换句话说,如果你指定jar:jar 目标,它只会运行jar:jar 目标来将你的代码打包到一个jar 中。如果您之前没有运行编译目标或以其他方式准备编译代码,这很可能会失败。

【讨论】:

我习惯说“Maven 通过所有阶段(直到并包括给定的阶段)”而不是 “运行”“执行”(后者在 Maven 的构建生命周期简介中被调用)。这样将它与真正执行的目标代码区分开来。但这可能是个人喜好。 但是我们也可以运行不属于任何阶段的目标,即mvn archetype:generate,那么maven只执行目标? @Pace 你有最后一段的参考吗?我一直对此表示怀疑,并在这里尝试了一个简单的项目:mvn test 运行:--- maven-resources-plugin:2.6:resources ... --- maven-compiler-plugin:3.1:compile ... --- maven-resources-plugin:2.6:testResources ... --- maven-compiler-plugin:3.1:testCompile ... --- maven-surefire-plugin:2.12.4:test,而mvn compiler:testCompile 只是运行--- maven-compiler-plugin:3.1:testCompile ... @Pace mvn clean compiler:testCompile 运行 --- maven-clean-plugin:2.5:clean ... --- maven-compiler-plugin:3.1:testCompileFailed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile (default-cli) on project mvnphase: Compilation failure ... cannot find symbol ... symbol: variable MvnPhase 失败(其中 MvnPhase 是测试类中引用的测试类)。如果明确调用目标,显然不会调用阶段。 根据 geroldbroser 和 @kekko12 的输入,我更新了最后一段,说明当指定目标时,仅运行该目标,而不是所有前面的阶段。【参考方案2】:

生命周期是一系列命名的阶段。 阶段按顺序执行。执行一个阶段意味着执行所有之前的阶段。

插件是 goals 的集合,也称为 MOJO (Maven Old Java 对象)。 类比:插件是一个类,目标是类中的方法。

Maven 基于构建生命周期的核心概念。在每个构建生命周期中有构建阶段,在每个构建阶段中有构建目标

我们可以执行构建阶段或构建目标。在执行构建阶段时,我们会在该构建阶段执行所有构建目标。构建目标被分配给一个或多个构建阶段。我们也可以直接执行构建目标。

有三大内置构建生命周期

    默认 干净 网站

Each Build Lifecycle is Made Up of Phases

例如,default 生命周期包含以下构建阶段

◾validate - validate the project is correct and all necessary information is available
◾compile - compile the source code of the project
◾test - test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
◾package - take the compiled code and package it in its distributable format, such as a JAR.
◾integration-test - process and deploy the package if necessary into an environment where integration tests can be run
◾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.

所以要完成上述阶段,我们只需要调用一个命令:

mvn <phase>  Ex: mvn install 

对于上述命令,从第一个阶段开始,所有阶段依次执行,直到“安装”阶段。 mvn 可以执行一个目标或一个阶段(甚至多个目标或多个阶段),如下所示:

mvn clean install plugin:goal  

但是,如果您想自定义用于引用插件的前缀,您可以通过 plugin's POM. 中 maven-plugin-plugin 上的配置参数直接指定前缀

构建阶段由Plugin 目标组成

Maven 的大部分功能都在插件中。插件提供一组 goals 可以使用以下语法执行:

 mvn [plugin-name]:[goal-name]

例如,可以通过运行mvn compiler:compile 使用编译器插件的编译目标来编译Java 项目。

构建生命周期是一个命名阶段列表,可用于为目标执行指定顺序。

插件提供的目标可以与生命周期的不同阶段相关联。例如,默认情况下,目标compiler:compilecompile相关联phase,而 goal surefire:testtest phase 相关联。考虑以下命令:

mvn test

执行上述命令时,Maven 会运行与每个阶段相关联的所有目标,直到并包括 test 阶段。在这种情况下,Maven 运行与process-resources 阶段关联的resources:resources 目标,然后运行compiler:compile,依此类推,直到最终运行surefire:test 目标。

但是,即使构建阶段负责构建生命周期中的特定步骤,它执行这些职责的方式也可能会有所不同。这是通过声明绑定到这些构建阶段的插件目标来完成的。

插件目标表示有助于构建和管理项目的特定任务(比构建阶段更精细)。它可能绑定到零个或多个构建阶段。未绑定到任何构建阶段的目标可以通过直接调用在构建生命周期之外执行。执行顺序取决于调用目标和构建阶段的顺序。例如,考虑下面的命令。 cleanpackage 参数是构建阶段,而 dependency:copy-dependencies 是(插件的)目标。

mvn clean dependency:copy-dependencies package

如果要执行此操作,将首先执行 clean 阶段(这意味着它将运行清洁生命周期的所有先前阶段,加上 clean 阶段本身),然后是 dependency:copy-dependencies 目标,之前最后执行package 阶段(以及默认生命周期的所有先前构建阶段)。

此外,如果一个目标绑定到一个或多个构建阶段,则该目标将在所有这些阶段中被调用。

此外,构建阶段还可以绑定零个或多个目标。如果构建阶段没有绑定目标,则该构建阶段将不会执行。但是,如果它绑定了一个或多个目标,它将执行所有这些目标。

Built-in Lifecycle Bindings 默认情况下,某些阶段具有绑定到它们的目标。而对于默认生命周期,这些绑定取决于打包值。

Maven 架构:

Reference 1Reference 2

Maven 生命周期映射的 Eclipse 示例

【讨论】:

如果我有 2 个配置文件,我可以先运行配置文件 1 的所有插件,然后运行配置文件 2 的所有插件吗? [plugin-name] 在示例中的mvn [plugin-name]:[goal-name] 是一个plugin prefix。 mvn clean install 不仅可以“用于多模块场景”。多模块是一个完全不同的话题。 同一阶段的目标是否遵守任何顺序? 本文大部分内容是从Maven documentation 逐字复制而来。这一点应该说清楚! 真棒来源!【参考方案3】:

详细的定义在Maven site's page Introduction to the Build Lifecycle,不过我试过summarize:

Maven 定义了构建过程的 4 项:

    生命周期

    三个内置生命周期(又名构建生命周期):defaultcleansite。 (Lifecycle Reference)

    阶段

    每个生命周期都由阶段组成,例如对于default 生命周期:compiletestpackageinstall

    插件

    提供一个或多个目标的工件。

    基于打包类型(jarwar 等)插件的目标默认绑定到阶段。 (Built-in Lifecycle Bindings)

    目标

    执行的任务(动作)。一个插件可以有一个或多个目标。

    configuring a plugin in a POM时需要指定一个或多个目标。此外,如果插件没有定义默认阶段,则可以将指定的目标绑定到阶段。

Maven 可以通过以下方式调用:

    一个阶段(例如cleanpackage&lt;plugin-prefix&gt;:&lt;goal&gt;(例如dependency:copy-dependencies&lt;plugin-group-id&gt;:&lt;plugin-artifact-id&gt;[:&lt;plugin-version&gt;]:&lt;goal&gt;(例如org.apache.maven.plugins:maven-compiler-plugin:3.7.0:compile

任何或全部的一种或多种组合,例如:

mvn clean dependency:copy-dependencies package

【讨论】:

只有生命周期阶段才真正有意义地被视为“步骤”(构建过程)。我宁愿称它为 4 个实体/项目/事物 当我看到Build Phase 的世界时,我认为它是生命周期中的另一个阶段,这让我感到困惑。 很好的答案。一个小提示:关于最后一节“可以调用 Maven”,还有第四个选项(从 Maven 3.3.1 开始),它是 plugin:goal@executation_id 例如mvn antrun:run@my-execution 见***.com/questions/3166538/…【参考方案4】:

选择的答案很棒,但我仍然想在主题中添加一些小东西。插图。

它清楚地展示了不同阶段如何绑定到不同的插件以及这些插件公开的目标。

那么,让我们来看看一个运行类似mvn compile的案例:

这是一个执行编译器plugin阶段 编译目标 编译器插件有不同的目标。对于mvn compile,它映射到特定目标,即编译目标。 和运行mvn compiler:compile一样

因此,阶段由插件目标组成

链接到reference

【讨论】:

为什么mvn test指向package,而mvn install指向deploy 看起来像插图错误,感谢您的注意(在网络上创建)。 你从哪里得到的插图?您检查过版权和使用条款吗? @Abdull 图片取自这里carminespagnuolo.eu/otheractivities/tutorato/PR-2014-2015/…(它也出现在许多其他网页中)将其添加到答案中。感谢您提出这一点,不知道它的重要性。 图中从阶段到插件的指针也不太对,jar 插件实际上运行在package 阶段。阶段和插件之间的夹层中的 pom 有点令人困惑(我认为这应该意味着在 pom 中,除了默认绑定之外,您还可以配置哪些插件在哪些阶段中运行)。不过,一般原则是正确的。【参考方案5】:

我相信已经提供了一个很好的答案,但我想添加一个易于理解的图表,显示不同的 3 个生命周期(buildcleansite)以及每个。

粗体的阶段 - 是常用的主要阶段。

【讨论】:

generate-resources 出现两次,generate-sources 不见了。【参考方案6】:

感谢 Sandeep Jindal 和 Premraj。他们的解释帮助我在困惑了一段时间后理解。

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

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

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

1.生命周期与阶段

Life Cyclephase 的集合,请参阅此处Life Cycle References。当你调用一个phase时,它也会调用它之​​前的所有phase

例如,清洁生命周期有 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

更多细节和完整示例在https://www.surasint.com/maven-life-cycle-phase-and-goal-easy-explained/

【讨论】:

【参考方案7】:

具有阶段和目标的 Maven 工作术语。

阶段:Maven阶段是一组与2或3个目标相关的动作

例如:- 如果你运行 mvn clean

这是执行目标 mvn clean:clean 的阶段

Goal:Maven 目标以阶段为界

供参考 http://books.sonatype.com/mvnref-book/reference/lifecycle-sect-structure.html

【讨论】:

它不一定是“与 2 或 3 个目标相关联”。也可以是一个多于三个【参考方案8】:

有以下三个内置的构建生命周期:

默认 干净 网站

生命周期默认值 -> [验证、初始化、生成源、流程源、生成资源、流程资源、编译、流程类、生成测试源、流程测试-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify 、安装、部署]

生命周期清理 -> [pre-clean, clean, post-clean]

生命周期站点 -> [pre-site, site, post-site, site-deploy]

流程是顺序的,例如对于default生命周期,它从validate开始,然后是initialize等等...

您可以通过启用mvn 的调试模式来检查生命周期,即mvn -X &lt;your_goal&gt;

【讨论】:

以上是关于什么是 Maven 目标和阶段,它们有什么区别?的主要内容,如果未能解决你的问题,请参考以下文章

4maven——构建生命周期

Maven - 为什么mvn install会启动编译或测试阶段?

maven依赖树输出中的“+-”和“\-”有啥区别?

maven install 与install:install 的区别

请问maven是啥?怎么使用?

机器学习中的目标函数损失函数代价函数有什么区别?