在项目的多个模块中,往往不同的模块会有相同的配置,比如,都同时依赖junit 构件 ,都连接到同一个私服,没错,这就是重复!重复往往意味着浪费更多的劳动力和存在一些潜在的问题,maven提供了继承的特性供我们解决这类问题 。
假设现在一个项目有两个模块, helloMvnPersist、helloMvnService,两个模块都依赖的Junit构件,现在,我们要新建一个项目helloMvnParent做为这两个项目的父项目,我们把一些重复的配置编写到helloMvnParent的pom文件中,让helloMvnPersist、helloMvnService分别继承自 helloMvnParent,这样就消除了重复带来的潜在问题,同时也简化了配置。
helloMvnParent的pom配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.helloMvn</groupId>
<artifactId>helloMvnParent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>HelloMvn Parent</name>
</project>
需要着重注意的是:
1.继承和聚合一样,父项目只需要一个pom文件就可以 。
2.packaging标签要配置为pom .
这样,helloMvnParent的pom就配置好了 ,下面,我们来配置子项目helloMvnService的 pom ,
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.helloMvn</groupId>
<artifactId>helloMvnParent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../helloMvnParent/pom.xml</relativePath>
</parent>
<artifactId>helloMvnService</artifactId>
<name>HelloMvn Service</name>
</project>
需要着重注意的是:
1. 引入parent 标签,groupId、groupId、version要和父项目一一对应,其实也不难理解,虽然helloMvnParent只有一个pom文件,但也属于一个构件,是构件就应该有坐标标识,供其他项目下载引用
2.引入relativePath标签,relativePath标签和聚合中的module标签功能一致,其作用是告诉子项目父项目的pom文件所在的位置 如果不写,默认为../pom.xml,也就是说maven 默认的父pom在上一层目录下,../helloMvnParent/pom.xml则是指helloMvnParent和helloMvnService在同级目录
3. relativePath非常关键,如果子模块没有正确的设置relativePath,maven在构建时将无法找到父pom,这将直接导致构建失败。
4.helloMvnService只配置了artifactId,不代表没有配置group和version,这两个元素被helloMvnService从父pom中继承了下来.
maven常的继承的元素有 groupId,version,properties,dependencies,dependencyManagement,repositories,build等等。
5.假如helloMvnService依赖构件A,helloMvnPersist依赖构件B,而构件A和B都被配置在了父pom中,这样helloMvnService就不可避免的继承了对构件B的依赖,事实上helloMvnService完全不需要依赖构件B,同时helloMvnService也不可避免的继承了对构件A的依赖,这样做显然是不合理的,因此maven 提供了dependencyManagement标签来灵活配置对父pom对构件的依赖,父pom修改如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.helloMvn</groupId>
<artifactId>helloMvnParent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>HelloMvn Parent</name>
<properties>
<junit.version>3.8.2</junit.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
可以看到,父pom添加了对junit 的依赖,dependencyManagement标签的作用是 不会给自身引入任何依赖,也不会被其它子模块继承,如果其它子模块需要继承,则需要显示的声明一下,配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.helloMvn</groupId>
<artifactId>helloMvnParent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../helloMvnParent/pom.xml</relativePath>
</parent>
<artifactId>helloMvnPersist</artifactId>
<name>helloMvn Persist</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
</project>
可以看到子pom只需要声明groupId 和artifactId就可以了,这样做虽然只省去了version的声明,但是在父pom中用dependencyManagement统一声明依赖,其他子模块就无需声明依赖的版本,从而避免各个模块依赖不同版本的同一个构件,这样可以降低依赖冲突。