有些情况你会想要一个项目从父POM中继承一些值。你可能正构建一个大型的系统,你不想一遍又一遍的重复同样的依赖元素。如果你的项目通过parent元素使用继承,你就可以避免这种重复。当一个项目声明一个parent的时候,它从父项目的POM中继承信息。它也可以覆盖父POM中的值,或者添加一些新的值。
所有的Maven
POM从父POM中继承值。如果一个POM没有通过parent元素指定一个直接的父项目,那这个POM就会从超级POM继承值。Example 9.12, “项目继承”展示了a-parent
的parent
元素,它继承了a-parent
项目定义的POM。
Example 9.12. 项目继承
<project> <parent> <groupId>com.training.killerapp</groupId> <artifactId>a-parent</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>project-a</artifactId> ... </project>
在project-a
中运行会mvn
help:effective-pom显示一个POM,该POM合并了超级POM,a-parent
中定义的POM,以及project-a
中定义的POM。project-a
显式的和隐式的继承关系如Figure 9.4, “a-parent和project的项目继承关系”所示:
当一个项目指定一个父项目的时候,Maven在读取当前项目的POM之前,会使用这个父POM作为起始点。它继承所有东西,包括groupId
和version
。你会注意到project-a
没有指定groupId
和version
,它们从a-parent
继承而来。有了parent元素,一个POM就只需要定义一个artifactId
。但这不是强制的,project-a
可以有一个不同的groupId
和version
,但如果不提供值,Maven就会使用在父POM中指定的值。如果你开始使用Maven来管理和构建大型的多模块项目,你就会常常创建许多共享一组通用的groupId
和version
的项目。
当你继承一个POM,你可以选择直接使用继承的POM信息,或者选择覆盖它。以下是一个Maven POM从它父POM中继承的项目列表:
-
定义符(
groupId
和artifactId
中至少有一个必须被覆盖) -
依赖
-
开发者和贡献者
-
插件列表
-
报告列表
-
插件执行 (id匹配的执行会被合并)
-
插件配置
当Maven继承依赖的时候,它会将父项目中定义的依赖添加到子项目中。你可以使用Maven的这一特征来指定一些在所有项目被广泛使用的依赖,让它们从顶层POM中继承。例如,如果你的系统全局使用Log4J日志框架,你可以在你的顶层POM中列出该依赖。任何从该项目继承POM信息的项目会自动拥有Log4J依赖。类似的,如果你能确定每个项目都在使用同样版本的一个Maven插件,你可以在顶层父POM的pluginManagement
元素中显式的列出该Maven插件的版本。
Maven假设父POM在本地仓库中可用,或者在当前项目的父目录(../pom.xml
)
中可用。如果两个位置都不可用,默认行为还可以通过relativePath
元素被覆盖。例如,一些组织更喜欢一个平坦的项目结构,父项目的pom.xml
并不在子项目的父目录中。它可能在项目的兄弟目录中。如果你的子项目在目录./project-a
中,父项目在名为./a-parent
的目录中,你可以使用如下的配置来指定parent-a
的POM的相对位置。
<project> <parent> <groupId>org.sonatype.mavenbook</groupId> <artifactId>a-parent</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../a-parent/pom.xml</relativePath> </parent> <artifactId>project-a</artifactId> </project>