多模块项目和父项目的区别

Differences between a multi-module project and a parent project

在 Maven 的多模块项目中,我们有一个父 pom,其模块在 <modules> 标记中定义,并且在每个模块中,我们定义父 pom 是什么。

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

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

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

如果你想在我看来重用模块,那么你需要将这些模块作为一个库,并通过 dependency 标签将它们添加为一个库。

Why this two-way definition?

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

Why not define just in the parent?

如果你只在父pom的modules标签中定义它们,你将只使用Maven的reactor/aggregation特性。

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

通过在子 poms 中声明父工件来启用继承:

<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>

事实上,您可以使用项目继承、项目组合、none 或两者。

这确实是一个设计选择,应该根据项目和他们的需求之间的关系来做。

这两个功能可以参考this interesting point on the Maven documentation

Project Inheritance vs Project Aggregation

If you have several Maven projects, and they all have similar configurations, you can refactor your projects by pulling out those similar configurations and making a parent project. Thus, all you have to do is to let your Maven projects inherit that parent project, and those configurations would then be applied to all of them.

And if you have a group of projects that are built or processed together, you can create a parent project and have that parent project declare those projects as its modules. By doing so, you'd only have to build the parent and the rest will follow.

But of course, you can have both Project Inheritance and Project Aggregation. Meaning, you can have your modules specify a parent project, and at the same time, have that parent project specify those Maven projects as its modules.

举例说明。

这是一个多模块项目的父项目 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>

这是儿童 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 决定覆盖它们的情况除外)。