这里相对较新的开发人员,尽管我已经使用了一段时间,但我希望巩固我的 Maven 基础。我的部分问题是我没有使用 Ant 的经验,这似乎是许多解释的根源。我一直在阅读和观看教程,并且不断听到相同的术语:
- 生命周期
- 阶段
- 插入
- 目标
据我所知,生命周期似乎是最广泛的,由阶段、插件和/或目标组成(或由其完成)。
问题:您能否提供有关这些术语如何相关以及最常见示例的任何信息?
越明确和基本越好!
这里相对较新的开发人员,尽管我已经使用了一段时间,但我希望巩固我的 Maven 基础。我的部分问题是我没有使用 Ant 的经验,这似乎是许多解释的根源。我一直在阅读和观看教程,并且不断听到相同的术语:
据我所知,生命周期似乎是最广泛的,由阶段、插件和/或目标组成(或由其完成)。
问题:您能否提供有关这些术语如何相关以及最常见示例的任何信息?
越明确和基本越好!
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:
...
...请参阅下面的参考中的实际输出或Maven,构建生命周期简介。
参考
如果您想知道 Maven 如何知道在 POM 中没有任何目标绑定的情况下该做什么,那么default-bindings.xml
该页面底部有一个链接,该链接位于<Your Maven installation>/lib/maven-core-x.y.z.jar/META-INF/plexus/default-bindings.xml
.
内置生命周期的阶段(clean、default、site)在<Your Maven installation>/lib/maven-core-x.y.z.jar/META-INF/plexus/components.xml
下面声明<component-set><components><component><role>org.apache.maven.lifecycle.Lifecycle
。另请参阅生命周期参考。
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: [...]
)→</li>
artifactId
和指定version
),其compile
目标是 →</li>
execution
由与定义id
default-compile
。它是独一无二的,因为您确实可以将相同的目标(同一个插件)绑定到不同的阶段或同一个阶段但在不同的执行中(即使用不同的配置)。例如,在阶段maven-compiler-plugin
(不同的阶段)期间也使用来在不同的执行()中编译测试代码(通过其目标)。您还可以在不同阶段编译(使用相同的插件和目标)一些自动生成的代码,这些代码由您在 POM 中指定的执行定义(并且可能是不同的配置)。test-compile
testCompile
default-testCompile
默认执行通过Maven 打包绑定提供开箱即用,也就是说,默认情况下(并且强制约定优于配置)Maven 已经在某些阶段调用了某些目标(标准插件的)。这些默认调用的执行 ID 是根据某些约定定义的。
这也解释了为什么如果你真的想覆盖一个 Maven 构建的默认行为(绑定),你需要在你的 POM 中为同一个插件指定(覆盖)完全相同的执行 ID。例如,您可以跳过编译,只需定义具有maven-compiler-plugin
相同default-compile
id 但绑定到不存在的阶段(或空的阶段)的执行。
简而言之:执行告诉 Maven 在哪个阶段使用哪个配置执行哪个目标。
默认情况下提供了一些执行(默认绑定),这解释了为什么只有6行的maven 最小 pom已经可以做很多事情(编译、测试、打包等):在某些阶段执行标准插件的目标:这是约定配置。然后,通过配置,您可以向构建中添加东西(执行)或影响已配置插件的行为(在这种情况下,没有部分,但就足够了)。pom.xml
executions
configuration
是的,您可以跳过构建周期(及其阶段)并直接调用(插件的)目标。想象一下:
mvn compiler:compile
mvn compiler:testCompile
mvn surefire:test
mvn jar:jar
(注意:您也可以仅在一次调用中调用 inline)
在这里,我们正在编译应用程序代码、测试代码、执行测试和打包:想象一下这将是多么手动、容易出错、重复和耗时。约定优于配置有助于我们:Maven 引入了构建生命周期和阶段。默认生命周期(没有名称,即默认),提供了基于最佳实践和约定(Maven 的口头禅)的一系列阶段。
如果您想实现与上述相同的效果,只需运行:mvn package
它会自动编译、测试和打包您的项目。如何?调用插件。也就是说,阶段是有意义且可配置的插件(目标)执行集。为了使其更加标准,对于每个阶段,Maven 将首先调用任何先前的阶段,因此例如,如果您想测试,您将确保首先编译。
ps 请注意,当为同一个目标指定多个目标时execution
,您仍然会在构建日志中清楚地看到两个不同目标的两个不同执行(具有相同的 id)(因此,仍然是唯一的元组)。
归功于 Sandeep Jindal 和 Premraj(从这里什么是 Maven 目标和阶段,它们有什么区别?)。他们的解释帮助我理解。
我在这里创建了一些完整的代码示例和一些简单的解释https://www.surasint.com/maven-life-cycle-phase-and-goal-easy-explained/。我认为这可能有助于其他人理解并且可以直接尝试一些东西。
简而言之,从链接中,您不应该试图同时了解所有三个,首先您应该了解这些组中的关系:
1. 生命周期与阶段
生命周期是按顺序排列的阶段的集合,请参见此处生命周期参考。当你调用一个阶段时,它也会调用它之前的所有阶段。
例如,清洁生命周期有 3 个阶段(清洁前、清洁、清洁后)。
mvn clean
它将调用pre-clean和clean。
2. 插件与目标
目标就像Plugin中的一个动作。所以如果插件是一个类,那么目标就是一个方法。
你可以这样称呼一个目标:
mvn clean:clean
这意味着“在 clean 插件中调用 clean 目标”(此处与 clean 阶段无关。不要让“clean”这个词让您感到困惑,它们是不一样的!请参阅我上面的链接中的完整解释)
3. 现在阶段和目标之间的关系:
阶段可以(预)链接到目标。例如,通常,清洁阶段链接到清洁目标。因此,当您调用此命令时:
mvn clean
它将调用 pre-clean 阶段和链接到 clean:clean 目标的 clean 阶段。
它几乎与以下内容相同:
mvn pre-clean clean:clean
迟来的另一张图
来自这个非常好的教程:
生命周期、生命周期阶段、插件和插件目标是 Maven 的核心。
mvn
命令调用生命周期阶段时,前面的所有阶段都会依次执行。当我们mvn package
在 Java 项目中运行时,Maven 将插件目标绑定到生命周期阶段,如下图所示:
所以要进一步解释这里概述的
Maven 构建在生命周期中被拆分,它们是:
每个周期都分为几个阶段。例如,构建分为以下几个阶段:
阶段的目标是在阶段之前或之后运行,例如:
如果您愿意,您可以将目标视为额外的“插入”阶段。在此处阅读或查看@Gerolds 答案以了解详细信息。