【发布时间】:2018-01-13 21:54:24
【问题描述】:
在 Maven 的多模块项目中,我们有一个父 pom,其模块在 <modules> 标签中定义,在每个模块中,我们定义父 pom 是哪个。
-
为什么是这种双向定义?
-
为什么不在模块的父部分定义它们之间的关系
-
如果模块总是绑定到一个父级,我应该如何重用它们?
【问题讨论】:
标签: java maven maven-module
在 Maven 的多模块项目中,我们有一个父 pom,其模块在 <modules> 标签中定义,在每个模块中,我们定义父 pom 是哪个。
为什么是这种双向定义?
为什么不在模块的父部分定义它们之间的关系
如果模块总是绑定到一个父级,我应该如何重用它们?
【问题讨论】:
标签: java maven maven-module
为什么是这种双向定义?
这不是强制性的。这是一种设计选择。
为什么不在父级中定义?
如果你只在父pom的modules标签中定义它们,你只会使用Maven的reactor/aggregation特性。
1) 聚合(超级聚合器项目中的<modules> 声明)主要提供以下功能:
通过在父 pom 中声明要聚合的模块来启用聚合模块:
<modules>
<module>my-child</module>
<module>my-other-child</module>
</modules>
但聚合不提供继承。
2)项目继承(子模块中的<parent>声明)提供了从父声明到子模块的多个事物的继承:
从实际文档来看,父 POM 中的大多数元素都由其子代继承:
groupIdversiondescriptionurlinceptionYearorganizationlicensesdeveloperscontributorsmailingListsscmissueManagementciManagementpropertiesdependencyManagementdependenciesrepositoriespluginRepositoriesbuildplugin executions with matching idsplugin configurationreportingprofiles通过在子 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>
实际上,您可以使用项目继承、项目组合,或者两者都不使用。
这确实是一个设计选择,应该根据项目和他们的需求之间的关系来做。
这两个功能可以参考this interesting point on the Maven documentation:
项目继承与项目聚合
如果您有多个 Maven 项目,并且它们都有相似的 配置,您可以通过拉出那些来重构您的项目 类似的配置并制作父项目。因此,你所拥有的一切 要做的是让您的 Maven 项目继承该父项目,并且 然后这些配置将应用于所有这些。
如果您有一组正在构建或处理的项目 一起,您可以创建一个父项目并拥有该父项目 将这些项目声明为其模块。通过这样做,你只需要 构建父级,其余的将随之而来。
当然,您可以同时拥有项目继承和项目 聚合。意思是,你可以让你的模块指定一个父级 项目,同时,让该父项目指定那些 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 中设置的一些信息。
我相信这可能有更多原因,但这对我来说是最明显的。
如果你想在我看来重用模块,那么你需要将这些模块作为一个库,并通过dependency标签将它们添加为一个库。
【讨论】: