Maven 默认生命周期和插件部分

Posted

技术标签:

【中文标题】Maven 默认生命周期和插件部分【英文标题】:Maven default life-cycle and plugins section 【发布时间】:2016-08-02 23:48:20 【问题描述】:

如果我错了,请纠正我。如果没有在 Maven pom.xml 中定义打包类型,则默认使用 jar 生命周期。

每个 Maven 打包类型都有一个默认的构建生命周期和相关的默认目标。 (我们可以将目标视为插件+命令

生命周期阶段目标

流程资源资源:资源 编译编译器:编译 流程测试资源资源:testResources 测试编译编译器:testCompile 测试万无一失:测试 包jar:jar 安装安装:安装 部署部署:部署

我的问题是: 在定义打包类型时,我们可以说pom.xml 插件部分填充了该打包构建生命周期的默认插件和目标吗?

还有: 如果我们在插件部分定义一个插件,比如编译器插件,并给出它的配置,这些配置会覆盖插件默认配置吗?

【问题讨论】:

【参考方案1】:

如果在maven pom.xml中没有定义打包类型,则使用jar lifecyle。

几乎正确,jar 不是一个生命周期,它是一个包装。 Maven 有三个 build life cycles(干净、默认、站点),可以应用于任何包装。

根据官方Maven model

packaging 该项目产生的工件类型,例如jar war ear pom。插件可以创建自己的包装,因此也可以创建自己的包装类型,因此此列表不包含所有可能的类型。默认值为jar


每个 Maven 打包类型都有一个默认的构建生命周期

它没有默认生命周期,您在其项目上调用默认生命周期。默认生命周期有default bindings,即插件已经按照定义的packaging类型默认附加到默认生命周期的各个阶段。

Maven 的core concepts 之一是约定优于配置。它的默认绑定强制执行此原则,已经为给定包装提供了某些插件的某些目标的执行。 例如,默认情况下,已经希望编译(在compile 阶段通过maven-compiler-plugin 及其compile 目标),在test 阶段通过maven-surefire-plugin 及其test 目标) 并在应用默认 (jar) 打包时打包(通过maven-jar-plugin 及其jar 目标在package 阶段)您的项目。 (注意模式:我提到了一个插件、一个目标、一个阶段,也就是默认绑定)。

这就是minimal pom 已经可以做很多事情的原因:再次强调,它是约定优于配置。


在定义打包类型时,我们可以说好像 pom.xml 插件部分填充了该打包构建生命周期的默认插件和目标吗?

确实,这就像使用默认配置填充构建plugins 部分,执行默认附加插件和目标并分配给某些阶段。 另外请注意,如果您添加相同插件和目标的进一步执行,它将在默认绑定指定的(之后)之上调用。如果需要,请参阅下文如何预防。


如果我们在插件部分定义一个插件,例如编译器插件, 并给它配置,这些配置会覆盖插件默认配置吗?

您可以定义更多插件和executions 的一个或多个目标,附加到某个阶段。每个execution 可以有一个自定义configuration。但是,configuration 不在任何 execution 部分中但声明为通用/全局配置,然后将应用于相关插件的任何执行,因此也应用于默认附加的插件通过包装绑定。

来自configuration 元素上的官方POM reference

默认行为是根据元素名称合并configuration元素的内容。如果子 POM 具有特定元素,则该值将成为有效值。如果子 POM 没有元素,但父 POM 有,则父值成为有效值。

关于execution 部分的configuration 元素:

configuration:同上,但将配置限制在这个特定的目标列表中,而不是插件下的所有目标。

这就是为什么您经常看到maven-compiler-plugin 的不同source/target 配置,而没有任何execution。它将应用于已通过默认绑定附加的compile(源代码编译)和testCompile(测试代码编译)目标的默认执行。

此外,您甚至可以覆盖默认绑定并将其从某个阶段删除它到不同的阶段或不存在的阶段(或空)阶段。因此,您将禁用默认的插件目标执行。您可以使用此技巧将您的插件目标执行添加为同一阶段的第一次执行:通过禁用默认执行,添加您的执行,然后重新定义默认执行(然后使用不同的 id)。然后,Maven 将遵循执行声明顺序。

检查 this SO answer 以了解如何生成执行 ID。这里的重点是,来自official Maven documentation

通过指定 POM 打包的默认生命周期映射绑定到构建生命周期的每个 mojo 将分配给它的执行 ID 为 default-goalName

【讨论】:

多么好的答案!非常感谢,这对我帮助很大! :) 我只有一个额外的疑问:假设我定义了另一个要调用的插件编译器绑定到编译阶段,首先执行的目标是:默认编译器插件的目标还是我的插件目标?跨度> @GionJh 默认绑定总是首先执行,如果您需要先执行您的目标,那么您可以使用一个技巧:覆盖默认执行 ID,将其绑定到空阶段(因此禁用它),然后定义您的执行,然后重新定义默认绑定执行。然后,maven 将使用执行声明的顺序。 @GionJh maven 在其核心使用的关于所有插件的标准和默认输入/输出/文件夹,所有 maven 标准插件(来自 Apache)都使用它们,但其他插件可能会忽略它们,而不是根据他们的需要要求它们或使它们可配置。它们强制执行我们通常执行插件目标的特定项目框架。 @GionJh 是的,但最好不要这样做,在大多数情况下默认值都很好,人们不会对错位感到惊讶

以上是关于Maven 默认生命周期和插件部分的主要内容,如果未能解决你的问题,请参考以下文章

Maven生命周期和插件

maven生命周期和插件

Maven生命周期和插件

Maven生命周期和插件

maven生命周期和插件

maven生命周期和插件