1.前言
我们先来看一个应用场景,使用maven将一个项目分给多个人并行开发,最终多人开发的多个工程整合成一个项目系统使用,这时就需要考虑不同开发人员在开发过程中使用的资源版本问题,一旦出现版本不兼容会造成测试成本过高,项目不能及时上线的严重问题.
2. 继承
2.1继承的意义
为了统一一个项目多模块并行开发的资源版本,maven出现了继承的功能,可以将一个大型项目分为父工程和子工程,其中父工程的唯一作用就是定义所有子模块工程的资源版本(父工程不编写代码,只编辑pom.xml文件)
上图中,还是2个模块开发者使用A.jar,由于继承了父工程,定义了A.jar的版本为1.0,所以子工程的A.jar不需要在添加版本的描述,直接就使用的是1.0版本的A.jar
3.2继承的实现
要想完成maven的继承我们应该按照以下几步执行
- 创建父工程
保证父工程的pom.xml文件中定义的打包packaging标签的类型是pom,一个java项目默认是jar类型,web项目默认是war类型,但是父工程必须是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>org.example</groupId>
<artifactId>maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
</project>
- 创建子工程
在子工程中使用parent标签,定义groupId artifactId version指向父工程.这样父工程的一些资源标签就可以被子工程使用了,父子继承的本质就是pom的重用复制。
注意:由于idea每个项目单独使用一个workspace工作空间所以父工程想要被继承,需要先安装到本地库 install,要不然就在idea中使用聚合(idea的聚合)在父工程下直接创建child工程,这里我们选择第二种.
<?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">
<parent>
<artifactId>maven-parent</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>maven-child</artifactId>
</project>
3.3继承的内容
通过上述案例我们实现了一个父工程下有一个子工程继承的项目结构,那么子工程能从父工程继承哪些内容呢?
本质上来讲,父子继承,子工程就是继承了父工程pom文件的一些标签资源.
有三种实现,分别比对说明
1.properties:定义一些当前项目使用的变量名称,在子类中可以通过$获取直接使用(缺点就是变量名称可以自由命名,如果很多,就很乱,每次获取都要去父类中寻找名称)
2.dependencies:一个项目的依赖,可以被子工程继承,而且是子工程无论用的到用不到依赖资源都会继承(缺点:继承--强制不能去除)
3.depencencyManagement:这个标签的作用是管理依赖的版本,当你使用到其中的某些依赖时,才引入,且不需要添加版本号(一般选择此种)
- properties
maven父级项目中可以使用properties定义一些当前项目使用的变量名称,例如:
<properties>
<!--可以在properties定义标签值-->
<spring.version>4.3.11.RELEASE</spring.version>
<junit.version>4.12</junit.version>
</properties>
子工程由于继承了这些标签的内容,可以直接使用
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
这种标签里的属性可以被子工程继承
- dependencies
一个项目的依赖,可以被子工程继承,而且是子工程无论用的到用不到依赖资源都会继承,虽然可以在父工程通过这种继承实现版本统一,但是显然不是最合理的.
父级工程定义依赖资源
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
子工程直接继承使用,虽然子工程没有直接添加这个依赖,但是会使用这个依赖
如果使用dependencies实现版本统一,会造成大量子工程根本用不到的依赖也必须使用.
- depencencyManagement
这个标签的作用是管理依赖的版本,当项目中使用dependencyManagement标签管理大量依赖时,并不会在项目中直接使用依赖.而是当你使用到其中的某些依赖时,不需要添加版本号.
这个标签用的最多的还是在父工程中实现依赖的版本管理,从而子工程不会强制使用这些依赖,只会继承依赖管理中的版本号,这样可以留给子工程选择的空间
例如:
父工程:在依赖管理中添加spring-beans依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
</dependencyManagement>
子工程
在依赖中只需要填写groupId artifactId,version直接继承自父工程
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
</dependencies>
这样相当于父工程管理的4.3.11就限制了子工程版本的内容
这就是父子继承的maven结构,一旦某个工程继承了一个父工程,那么他就会从父工程中获取很多已经定义好的资源,尤其是版本.