9

在 Maven 的多模块项目中,我们有一个父 pom,其模块在<modules>标签中定义,在每个模块中,我们定义父 pom 是哪个。

  • 为什么要进行这种双向定义?

  • 为什么不在模块的父部分定义它们之间的关系

  • 如果模块总是绑定到一个父级,我应该如何重用它们?

4

2 回答 2

22

为什么要进行这种双向定义?

这不是强制性的。这是一种设计选择。

为什么不只在父级中定义?

如果你只在 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决定覆盖它们)。

于 2017-08-06T13:48:37.147 回答
2

因为当你构建一些子模块时,它现在应该有一些元信息,例如依赖版本,并且将这些依赖关系放入父 pom 通常是更好的做法dependencyManagement,因为我会让所有子模块使用相同的库版本。还有另一个可能有用的元信息,例如properties.

所以,总而言之,当你构建一个特定的子模块时,maven 应该知道一些你通常想在父 pom.xml 中设置的信息。

我相信可能有更多的原因,但这对我来说是最明显的。

如果您想重用模块,那么您需要将这些模块作为库,并通过dependency标签将它们添加为库。

于 2017-08-06T13:45:01.880 回答