无论 POM 文件中是否显示的声明,所有的 POM 均继承自一个父 POM
,这个父 POM 被称为 Super POM
。在pom的继承关系中,子pom可以覆盖父pom中的配置
;如果子pom没有覆盖,那么父pom中的配置将会被继承
。按照这个规则,继承关系中的所有pom叠加到一起,就生成一个最终生效的pom
。maven实际运行的过程中,执行构建操作就是按照这个最终的pom
运行起来的。最终的pom也叫作有效pom翻译为effective POM
,通过mvn help:effective-pom
命令就可以查看项目的最终生成的pom(有效的pom)。
注意:假如项目当中引用了一个A的依赖,而A又引用了其他的依赖,通过
mvn help:effective-pom
查出来的pom并不会展示出来A引用的其他依赖(不展示并不代表不可以使用,具体是否可以使用要根据依赖的scope来决定的)。只会展示出来当前项目<parent>
所继承的依赖!可能他所继承的pom当中仍然继承了别的,会将所有层级汇集起来展示出来的!
下面进行示例演示,通过示例便可以一目了然:
项目是一个聚合项目,如下是父工程的pom.xml

这是一个common包,主要存放公共的一些配置

这是一个web工程

这时候我们对web工程进行使用mvn help:effective-pom
命令,看看他究竟执行的时候有哪些依赖。

他会把所有父 POM汇集到一起生成一个pom,lombok我是在父类当中引用的,可以发现最终pom当中他会继承过来的。

你可以看到 effective-pom 中包含了 Maven 在执行任务时需要用到的默认目录结构、输出目录、插件、仓库和报表目录等内容。

上图那些编译路径其实就是继承于超级pom, 超级 POM 路径位置:.\maven安装目录\lib\maven-model-builder.jar

我们可以将jar解压查看他的pom

查看超级 POM 结构
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- START SNIPPET: superpom -->
<project>
<modelVersion>4.0.0</modelVersion>
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
<build>
<directory>${project.basedir}/target</directory>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<finalName>${project.artifactId}-${project.version}</finalName>
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>${project.basedir}/src/test/resources</directory>
</testResource>
</testResources>
<pluginManagement>
<!-- NOTE: These plugins will be removed from future versions of the super POM -->
<!-- They are kept for the moment as they are very unlikely to conflict with lifecycle mappings (MNG-4453) -->
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
</plugin>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<reporting>
<outputDirectory>${project.build.directory}/site</outputDirectory>
</reporting>
<profiles>
<!-- NOTE: The release profile will be removed from future versions of the super POM -->
<profile>
<id>release-profile</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<inherited>true</inherited>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<updateReleaseInfo>true</updateReleaseInfo>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
<!-- END SNIPPET: superpom -->
我们使用和配置的POM其实大致是由三个层次组成的:
- 超级Pom:所有POM默认继承。
- 父POM:这一层可能没有,可能有一层,也可能有很多层,如果是springboot项目,我们往往会在pom.xml当中继承一个
spring-boot-starter-parent
。当然可能有的项目也不使用这个,而是直接引用spring-boot-dependencies
的依赖。关于spring-boot-starter-parent
详解:https://blog.csdn.net/weixin_43888891/article/details/130520345 - 当前pom.xml配置的POM:我们项目使用的一层。
在运行、编译的时候maven会生效这三层合并出来的pom。