相对较新的开发人员,尽管我已经使用了一段时间,但我希望能够巩固我的Maven基础知识。我的一部分问题是我没有使用Ant的经验,这似乎来自许多解释的起源。我一直在阅读和观看教程,我一直听到相同的条款:
从我所学到的,似乎生命周期是最广泛的,并且由阶段,插件和/或目标组成(或完成)。
问题:您能否提供有关这些术语如何相关的任何信息以及最常见的示例?
越明确,越基本越好!
@Drejc's answer完全不正确。
特别是:
每个阶段都有一个目标可以运行 之前或之后的阶段,例如: • 预安装 - ...... • 后包裹 - ...... 如果您愿意,可以将目标视为额外的“插入”阶段。
[删除我的错误陈述。]
Maven生命周期是一个(抽象)概念,涵盖了预期在项目开发生命周期中发生的所有步骤(或更好:Maven设计者决定支持的所有步骤)。这些步骤(或阶段)在Maven术语中称为阶段。
Maven插件是目标的供应商/供应商。目标中实施的代码是真正的主力。 (Maven in its core itself is just managing plugins and executing goals)。每个插件的目标都可以分配/绑定到任何生命周期阶段。
当调用mvn <phase>
时,Maven会传递所有阶段(每次)并执行所有目标(由插件提供),这些目标已经绑定到给定阶段之前和之前(包括)任何阶段。如果有一个阶段没有绑定目标,则不会做任何事情。但是这个阶段仍然存在。
即你不能“将'附加阶段'插入到Maven的内置生命周期中。他们已经在那里了!您可以使用自己的阶段开发自己的生命周期,但这远不仅仅是使用Maven。
称为“预安装”或“后包装”的阶段不存在。
参考文献:
default-bindings.xml
的链接位于<Your Maven installation>/lib/maven-core-x.y.z.jar/META-INF/plexus/default-bindings.xml
。
内置生命周期(干净,默认,站点)的阶段在<Your Maven installation>/lib/maven-core-x.y.z.jar/META-INF/plexus/components.xml
下的.../<component>/<role>org.apache.maven.lifecycle.Lifecycle
中声明。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 ---
这确实意味着(通过不同的粒度级别):
它是独特的,因为实际上你可以有相同的目标(相同的插件)绑定到不同的阶段或相同的阶段,但在不同的执行(即,具有不同的配置)。例如,maven-compiler-plugin
也在test-compile
phase(一个不同的阶段)中用于在不同的执行中编译测试代码(通过其testCompile
目标)(default-testCompile
)。您还可以在POM中指定的执行(可能是不同的配置)定义的不同阶段编译(使用相同的插件和目标)一些自动生成的代码。
默认执行是通过Maven packaging bindings开箱即用的,也就是说,默认情况下(并强制执行约定)Maven在某些阶段已经调用某些目标(标准插件)。这些默认调用的执行ID是根据certain conventions定义的。
这也解释了为什么如果你真的想要覆盖Maven构建的默认行为(绑定),你需要在POM中为同一个插件指定(覆盖)完全相同的执行id。例如,您可以跳过编译,只需使用相同的maven-compiler-plugin
id定义default-compile
的执行,但绑定到非现有阶段(或空阶段)。
简而言之:执行告诉Maven在哪个阶段执行哪个目标。
默认情况下会提供一些执行(默认绑定),这解释了为什么只有6行的maven minimal pom已经可以做很多事情(编译,测试,打包等):在某些阶段执行标准插件的目标:它是对配置的约定。然后,通过pom.xml
配置,你可以添加东西(执行)到构建或影响已配置的插件的行为(在这种情况下没有executions
部分,但只有configuration
就足够了)。
是的,您可以跳过构建周期(及其阶段)并直接调用目标(插件)。想象一下:
mvn compiler:compile
mvn compiler:testCompile
mvn surefire:test
mvn jar:jar
(注意:你也可以只在一个电话中调用内联)
在这里,我们正在编译应用程序代码,测试代码,执行测试和包:想象一下手动,容易出错,重复和耗时。约定优于配置有助于我们:Maven引入构建生命周期和阶段。默认生命周期(没有名称,即默认生命周期)根据最佳实践和约定(Maven的口头禅)提供了一系列阶段。
如果你想实现与上面相同的功能,只需运行:mvn package
,它将自动编译,测试和打包你的项目。怎么样?调用插件。也就是说,阶段是有意义且可配置的插件(目标)执行集。为了使其更加标准化,对于每个阶段,Maven将首先调用任何前一阶段,以便例如如果你想测试你,请确保你先编译。
附:请注意,在为同一个execution
指定多个目标时,您仍然会在构建日志中清楚地看到两个不同的目标(具有相同的ID),因为这两个目标(因此,仍然是唯一的元组)。
感谢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。当你调用一个阶段时,它也会调用它之前的所有阶段。
例如,清洁生命周期有3个阶段(预清洁,清洁,后清洁)。
mvn clean
它将称为预清洁和清洁。
2.插件与目标
目标就像插件中的动作。因此,如果插件是一个类,目标就是一种方法。
你可以这样打个目标:
mvn clean:clean
这意味着“在干净的插件中调用干净的目标”(这里没有涉及干净的阶段。不要让“干净”这个词让你困惑,它们不一样!请参阅上面链接中的完整说明)
3.现在阶段和目标之间的关系:
阶段可以(预)链接到目标。例如,通常,清洁阶段链接到清洁目标。所以,当你调用这个命令时:
mvn clean
它将称为预清洁阶段和清洁阶段,它与清洁目标相关联。
它几乎相同:
mvn pre-clean clean:clean
还有另一张图
来源:http://www.codetab.org/apache-maven-tutorial/,这是非常好的教程
生命周期,生命周期阶段,插件和插件目标是Maven的核心。
当我们在Java项目中运行“mvn package”时,Maven会将插件目标绑定到生命周期阶段,如下图所示。
所以如here概述的那样进一步解释
Maven构建在生命周期中分裂,这些是:
每个周期分为几个阶段。例如,构建分为以下阶段:
阶段的目标是在一个阶段之前或之后运行,例如:
如果您愿意,可以将目标视为额外的“插入”阶段。阅读here或了解@Gerolds answer了解详情。