一、继承概念
Maven 继承是指在 Maven 的项目中,让一个项目从另一个项目中继承配置信息的机制。继承可以让我们在多个项目中共享同一配置信息,简化项目的管理和维护工作。
二、继承作用
作用:在父工程中统一管理项目中的依赖信息,进行统一版本管理!
它的背景是:
- 对一个比较大型的项目进行了模块拆分。
- 一个 project 下面,创建了很多个 module。
- 每一个 module 都需要配置自己的依赖信息。
它背后的需求是:
- 多个模块要使用同一个框架,它们应该是同一个版本,所以整个项目中使用的框架版本需要统一管理。
- 使用框架时所需要的 jar 包组合(或者说依赖信息组合)需要经过长期摸索和反复调试,最终确定一个可用组合。这个耗费很大精力总结出来的方案不应该在新的项目中重新摸索。
如下图,由于 shop-user
和 shop-product模块
都需要 jackson-core依赖
,但是由于这两个模块是不同人写的,此时就会造成两个问题:
-
两个人导入的是不同版本的依赖,此相同的框架就有可能会出现版本不同的问题了,就需要通过相互协商解决,但是由于技术干太多了,协商不过来,此时就干脆索性不让你们两个自己导依赖的版本了,我可以统一在父工程中去引入依赖。
但这样的话,
shop-order
无需jackson-core的依赖
,但是你也引入了,因此这种方式并不推荐。 -
思路二:父工程中不引入依赖,只做依赖版本的声明,里面会使用
<dependencyManagement>
标签,这个标签是专门为版本管理去声明的,使用这个标签声明gav,它不会真正的导入依赖,它制作一个配置的声明,后期在子工程中需要导入依赖,只需要写ga即可,版本继承的都是父工程中声明的版本,它会根据你的ga找到对应的version。
通过在父工程中为整个项目维护依赖信息的组合既保证了整个项目使用规范、准确的 jar 包;又能够将以往的经验沉淀下来,节约时间和精力。
三、继承语法
父工程
1)创建Maven JavaSE工程
2)删掉父工程的src目录,只留一个pom文件,因为父工程不打包也不写代码
<groupId>com.atguigu.maven</groupId>
<artifactId>pro03-maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 当前工程作为父工程,它要去管理子工程,所以打包方式必须是 pom -->
<!--
Maven工程的打包方式
默认:jar
jar指的是普通的java项目打包方式! 项目打成jar包!
war指的是web项目打包方式!项目打成war包!
pom不会将项目打包!这个项目作为父工程,被其他工程聚合或者继承!
-->
<packaging>pom</packaging>
子工程
在父工程上new一个module,这样IDEA会帮我们维护到它们附属工程的关系。
只要是在parent06上创建,那么IDEA会默认选择它为父工程。并且GroupId会默认继承父工程的。
但其实这些都是可视化的方式认为它们是父子关系,而具体是靠子工程的pom配置文件中 <parent>
指定继承父工程的gav属性。
<!-- 使用parent标签指定当前工程的父工程 -->
<parent>
<!-- 父工程的坐标 -->
<groupId>com.atguigu.maven</groupId>
<artifactId>pro03-maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<!-- 子工程的坐标 -->
<!-- 如果子工程坐标中的groupId和version与父工程一致,那么可以省略 -->
<!-- <groupId>com.atguigu.maven</groupId> -->
<artifactId>pro04-maven-module</artifactId>
<!-- <version>1.0-SNAPSHOT</version> -->
四、父工程依赖统一管理代码示例
父工程声明版本信息
如下结构叫做导入依赖,如果在父工程中导入,那么所有子工程都有相应的依赖。
<dependencies>
<!-- 父工程添加依赖,会自动传递给所有子工程,不推荐! -->
</dependencies>
使用 <dependencyManagement>
叫做声明依赖,并不会下载依赖!它可以被子工程继承版本号。
<!-- 使用dependencyManagement标签配置对依赖的管理 -->
<!-- 被管理的依赖并没有真正被引入到工程 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
子工程引用版本
<!-- 子工程引用父工程中的依赖信息时,可以把版本号去掉。 -->
<!-- 把版本号去掉就表示子工程中这个依赖的版本由父工程决定。 -->
<!-- 具体来说是由父工程的dependencyManagement来决定。 -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
</dependencies>
当依赖加载后,子工程会导入该依赖,父工程没有,并且另外一个子工程中也没有!
但如果子工程导入依赖的时候自己加上了版本,那么就会覆盖父工程中的版本,但是不建议这样做。