在 Maven 的多模块项目中,我们有一个父 pom,其模块在<modules>
标签中定义,在每个模块中,我们定义父 pom 是哪个。
为什么要进行这种双向定义?
为什么不在模块的父部分定义它们之间的关系
如果模块总是绑定到一个父级,我应该如何重用它们?
在 Maven 的多模块项目中,我们有一个父 pom,其模块在<modules>
标签中定义,在每个模块中,我们定义父 pom 是哪个。
为什么要进行这种双向定义?
为什么不在模块的父部分定义它们之间的关系
如果模块总是绑定到一个父级,我应该如何重用它们?
为什么要进行这种双向定义?
这不是强制性的。这是一种设计选择。
为什么不只在父级中定义?
如果你只在 modules
父 pom 的标签中定义它们,你将只使用 Maven 的反应器/聚合特性。
1)聚合(<modules>
超级聚合器项目中的声明)主要提供以下功能:
通过在父 pom 中声明要聚合的模块来启用聚合模块:
<modules>
<module>my-child</module>
<module>my-other-child</module>
</modules>
但是聚合不提供继承。
2)项目继承(<parent>
子模块中的声明)提供了从父声明到子模块的多个事物的继承:
从实际文档来看,父 POM 中的大多数元素都由其子代继承:
groupId
version
description
url
inceptionYear
organization
licenses
developers
contributors
mailingLists
scm
issueManagement
ciManagement
properties
dependencyManagement
dependencies
repositories
pluginRepositories
build
plugin executions with matching ids
plugin configuration
reporting
profiles
通过在子 pom 中声明父工件来启用继承:
<parent>
<groupId>my-group</groupId>
<artifactId>my-parent</artifactId>
<version>1.0.0</version>
</parent>
<!-- You can note that groupId and version are not filled for the current project.
These are optional as inherited from the parent -->
<artifactId>my-artifact</artifactId>
实际上,您可以使用项目继承、项目组合,或者两者都不使用。
这真的是一个设计选择,应该根据项目之间的关系和他们的要求来做。
关于这两个特性,你可以参考Maven 文档中的这个有趣的点:
项目继承与项目聚合
如果您有多个 Maven 项目,并且它们都有相似的配置,您可以通过提取这些相似的配置并创建一个父项目来重构您的项目。因此,您所要做的就是让您的 Maven 项目继承该父项目,然后这些配置将应用于所有项目。
如果您有一组一起构建或处理的项目,您可以创建一个父项目并让该父项目将这些项目声明为其模块。通过这样做,您只需构建父级,其余的将随之而来。
但当然,您可以同时拥有 Project Inheritance 和 Project Aggregation。这意味着,您可以让您的模块指定一个父项目,同时让该父项目将这些 Maven 项目指定为其模块。
用一个例子来说明。
这是一个多模块项目的父 pom.xml。
<!-- PARENT POM -->
<groupId>com.example</groupId>
<artifactId>parent-demo</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>child-module</module>
</modules>
这是 Child Pom。
<!-- CHILD POM -->
<parent>
<groupId>com.example</groupId>
<artifactId>parent-demo</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>chile-module</artifactId>
在这里,child-module
继承parent-demo
,但parent-demo
不使用任何继承。
如果你愿意,你parent-demo
也可以使用继承,你可以parent-demo
像下面这样配置。
<!-- PARENT POM -->
<parent>
<groupId>com.example</groupId>
<artifactId>parent-deps</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../parent-deps</relativePath>
</parent>
<artifactId>parent-demo</artifactId>
<packaging>pom</packaging>
<modules>
<module>child-module</module>
</modules>
现在,您parent-demo
还继承了parent-deps
被级联到child-module
的配置(除非当然parent-demo
决定覆盖它们)。
因为当你构建一些子模块时,它现在应该有一些元信息,例如依赖版本,并且将这些依赖关系放入父 pom 通常是更好的做法dependencyManagement
,因为我会让所有子模块使用相同的库版本。还有另一个可能有用的元信息,例如properties
.
所以,总而言之,当你构建一个特定的子模块时,maven 应该知道一些你通常想在父 pom.xml 中设置的信息。
我相信可能有更多的原因,但这对我来说是最明显的。
如果您想重用模块,那么您需要将这些模块作为库,并通过dependency
标签将它们添加为库。