在 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 中的大多数元素都由其子代继承:
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>
实际上,您可以使用项目继承、项目组合,或者两者都不使用。
这真的是一个设计选择,应该根据项目之间的关系和他们的要求来做。
关于这两个特性,你可以参考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标签将它们添加为库。