A Project Object Model or POM is the fundamental unit of work in Maven. It is an XML file that contains information about the project and configuration details used by Maven to build the project. It contains default values for most projects. Examples for this is the build directory, which is `target`; the source directory, which is `src/main/java`; the test source directory, which is `src/test/java`; and so on. When executing a task or goal, Maven looks for the POM in the current directory. It reads the POM, gets the needed configuration information, then executes the goal.
Some of the configuration that can be specified in the POM are the project dependencies, the plugins or goals that can be executed, the build profiles, and so on. Other information such as the project version, description, developers, mailing lists and such can also be specified.
The Super POM is Maven's default POM. All POMs extend the Super POM unless explicitly set, meaning the configuration specified in the Super POM is inherited by the POMs you created for your projects. The snippet below is the Super POM for Maven 3.5.4.
### 2.2 Super POM
Super POM可称为超级POM,是Maven的默认POM。 所有项目的POM都隐式继承 Super POM,除非明确指定。 也就是说 Super POM 中指定的配置都会被我们项目的的POM继承。 下面是 [Maven 3.6.3 的超级POM文件](https://maven.apache.org/ref/3.6.3/maven-model-builder/super-pom.html)。
```xml
<project>
<modelVersion>4.0.0</modelVersion>
<!-- 中央仓库的地址 -->
<repositories>
<repository>
<id>central</id>
...
...
@@ -28,6 +44,7 @@ The Super POM is Maven's default POM. All POMs extend the Super POM unless expli
</repository>
</repositories>
<!-- 默认插件的中央仓库地址 -->
<pluginRepositories>
<pluginRepository>
<id>central</id>
...
...
@@ -43,6 +60,7 @@ The Super POM is Maven's default POM. All POMs extend the Super POM unless expli
@@ -171,6 +204,16 @@ Also, as mentioned in the [first section](https://maven.apache.org/guides/introd
Furthermore, you can see that in the minimal POM the *repositories* were not specified. If you build your project using the minimal POM, it would inherit the *repositories* configuration in the Super POM. Therefore when Maven sees the dependencies in the minimal POM, it would know that these dependencies will be downloaded from `https://repo.maven.apache.org/maven2` which was specified in the Super POM.
@@ -186,12 +229,35 @@ Elements in the POM that are merged are the following:
The Super POM is one example of project inheritance, however you can also introduce your own parent POMs by specifying the parent element in the POM, as demonstrated in the following examples.
<aname="Project_Inheritance"></a>
### 2.4 项目继承结构
POM中的这些元素会被合并:
- 依赖, dependencies
- 开发人员和贡献者
- 插件列表(包括报告插件)
- 插件的可执行信息
- 插件配置信息
- 资源信息
Super POM 是项目继承结构的一个示例,当然我们也可以在POM中直接指定 `parent` 元素来引入父POM,情况下面的演示。
#### Example 1
##### The Scenario
As an example, let us reuse our previous artifact, com.mycompany.app:my-app:1. And let us introduce another artifact, com.mycompany.app:my-module:1.
#### 第1个例子
##### 场景描述
假设我们的项目和前面一样,是 `com.mycompany.app:my-app:1`.
新引入的项目为 `com.mycompany.app:my-module:1`.
```xml
<project>
<modelVersion>4.0.0</modelVersion>
...
...
@@ -203,6 +269,8 @@ As an example, let us reuse our previous artifact, com.mycompany.app:my-app:1. A
And let us specify their directory structure as the following:
项目的目录结构如下:
```
.
|-- my-module
...
...
@@ -212,12 +280,20 @@ And let us specify their directory structure as the following:
**Note:**`my-module/pom.xml` is the POM of com.mycompany.app:my-module:1 while `pom.xml` is the POM of com.mycompany.app:my-app:1
Now, if we were to turn com.mycompany.app:my-app:1 into a parent artifact of com.mycompany.app:my-module:1,we will have to modify com.mycompany.app:my-module:1's POM to the following configuration:
@@ -236,6 +312,13 @@ Notice that we now have an added section, the parent section. This section allow
Alternatively, if we want the groupId and / or the version of your modules to be the same as their parents, you can remove the groupId and / or the version identity of your module in its POM.
Project Aggregation is similar to [Project Inheritance](https://maven.apache.org/guides/introduction/introduction-to-the-pom.html#Project_Inheritance). But instead of specifying the parent POM from the module, it specifies the modules from the parent POM. By doing so, the parent project now knows its modules, and if a Maven command is invoked against the parent project, that Maven command will then be executed to the parent's modules as well. To do Project Aggregation, you must do the following:
...
...
@@ -295,6 +400,18 @@ Project Aggregation is similar to [Project Inheritance](https://maven.apache.org
- Specify in the parent POM the directories of its modules (children POMs).
@@ -304,6 +421,13 @@ Given the previous original artifact POMs and directory structure:
**com.mycompany.app:my-app:1's POM**
#### 第3个例子
##### 场景描述
和前面的项目名称一样, POM 文件如下所示:
```xml
<project>
<modelVersion>4.0.0</modelVersion>
...
...
@@ -313,7 +437,7 @@ Given the previous original artifact POMs and directory structure:
</project>
```
**com.mycompany.app:my-module:1's POM**
子模块的 POM 文件如下所示:
```xml
<project>
...
...
@@ -324,7 +448,7 @@ Given the previous original artifact POMs and directory structure:
</project>
```
**directory structure**
目录结构为:
```
.
...
...
@@ -337,6 +461,11 @@ Given the previous original artifact POMs and directory structure:
If we are to aggregate my-module into my-app, we would only have to modify my-app.
##### 实现方式
我们修改父项目的POM文件,将子模块引入:
```xml
<project>
<modelVersion>4.0.0</modelVersion>
...
...
@@ -356,6 +485,13 @@ In the revised com.mycompany.app:my-app:1, the packaging section and the modules
Now, whenever a Maven command processes com.mycompany.app:my-app:1, that same Maven command would be ran against com.mycompany.app:my-module:1 as well. Furthermore, some commands (goals specifically) handle project aggregation differently.
@@ -363,6 +499,13 @@ Now, whenever a Maven command processes com.mycompany.app:my-app:1, that same Ma
But what if we change the directory structure to the following:
#### 第4个例子
##### 场景描述
如果父项目和子项目的目录结构不在一起怎么办? 比如:
```
.
|-- my-module
...
...
@@ -373,10 +516,16 @@ But what if we change the directory structure to the following:
How would the parent POM specify its modules?
parent POM 如何指定子模块的位置呢?
##### The Solution
The answer? - the same way as Example 3, by specifying the path to the module.
##### 实现方式
聪明的你是否想到了? 指定模块的相对目录即可:
```xml
<project>
<modelVersion>4.0.0</modelVersion>
...
...
@@ -391,6 +540,9 @@ The answer? - the same way as Example 3, by specifying the path to the module.
</project>
```
-------------
### 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.