本篇我们将学习maven的继承机制、依赖之间的传递性以及maven是如何解决依赖冲突的。
maven继承
在maven中,子项目是可以继承父项目的依赖的;
继承的意义
在构建多个模块的项目时候,往往会多有模块有相同的groupId、version,或者有相同的依赖,为了减少pom文件的配置、统一相同依赖的版本。可以将一个大型项目分为父工程和子工程,其中父工程的唯一作用就是定义所有子模块工程的资源版本(父工程不编写代码,只编辑pom.xml文件)
假设父项目引入了junit依赖,子项目继承父项目,虽然子项目没有引入junit依赖,但是子项目会继承父项目的依赖,从而使用junit依赖。请看例子:现在新建了一个父项目mavenParent,它的目录结构如下,有一个Hello.java和对应的测试类HelloTest.java。
而pom.xml引用了测试类junit,pom文件内容如下 :
<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.maven</groupId>
<!--构件名称-->
<artifactId>mavenParent</artifactId>
<!--版本号-->
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<!--添加依赖的jar包-->
<dependencies>
<!--项目要使用到junit的jar包,所以在这里添加junit的jar包的依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
</dependencies>
</project>
现在使用mvn install 命令打包父项目,并安装到本地仓库。
现在新建子项目mavenChild,pom文件如下:
<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.maven</groupId>
<!--构件名称-->
<artifactId>mavenChild</artifactId>
<!--版本号-->
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>com.maven</groupId>
<!--构件名称-->
<artifactId>mavenParent</artifactId>
<!--版本号-->
<version>0.0.1-SNAPSHOT</version>
</parent>
</project>
现在使用mvn clean install命令编译运行子项目,结果如下:
说明子项目继承了父项目的依赖junit,并使用该类测试。
继承元素
那么父pom文件中哪些元素可以被继承呢?
- groupId:项目组ID,项目坐标的核心元素
- version:项目版本,项目坐标的核心元素
- description:项目的描述信息
- organization:项目的组织信息
- properties:自定义的Maven属性,子pom也可以覆盖
- dependencies:项目的依赖配置
- repositories:项目的仓库配置
- build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等
- reporting:包括项目的报告输出目录配置、报告插件配置等。
- dependencyManagement:项目的依赖管理配置
-
pluginManagement 插件管理
这里重点说一下dependencyManagement和pluginManagement
(1)Maven 使用dependencyManagement 元素来提供了一种管理依赖版本号的方式。通常会在一个组织或者项目的最顶层的父POM中看到dependencyManagement 元素。使用pom.xml 中的dependencyManagement 元素能让所有在子项目中引用一个依赖而不用显式的列出版本号。
scope=import作用
- 当导入的模块没有 <scope>import</scope> 时,会将父模块所有的普通dependency全部继承到当前工程 dependencyManagement 中,并且会传递依赖。
- 有 <scope>import</scope> 继承的是 dependencyManagement;
- 没有 <scope>import</scope> 继承的是 dependency(也称为普通 dependency);
- 注意:在 dependencyManagement 中,scope = import 只能用于 type = pom 的 dependency 里;
(2)plugins可以处于两个地方1 pluginManagement结点下2 build根结点下
这二者的唯一区别是,只有当child的pom.xml使用了某个插件,pluginManagement下的对应插件才会生效.
注意:有些插件会被自动调用,比如将resources插件写在pluginManagement,无论child有没有使用resources插件,它都会生效,因process-resources阶段已经绑定了它,肯定会被调用.
传递依赖
在Maven中,依赖是可以传递的,就是说假设存在三个项目,分别是项目A,项目B以及项目C,假设C依赖于B,B依赖于A,那么我们可以根据Maven项目依赖的特征不难推出项目C也依赖于A。
依赖冲突
若项目中多个Jar同时引用了相同的Jar时,会产生依赖冲突,但Maven采用了两种避免冲突的策略,因此在Maven中是不存在依赖冲突的。
短路优先
本项目——>A.jar——>B.jar——>X.jar
本项目——>C.jar——>X.jar
若本项目引用了A.jar,A.jar又引用了B.jar,B.jar又引用了X.jar,并且C.jar也引用了X.jar。
在此时,Maven只会引用引用路径最短的Jar。
声明优先
若引用路径长度相同时,在pom.xml中谁先被声明,就使用谁。
参考文献
Maven之pom.xml配置文件详解_彩色贝的博客-优快云博客_pom.xml配置
pom.xml常用元素(maven)_乔志勇笔记的博客-优快云博客_pom元素
maven pom进阶教程 - 插件与继承(plugin & inherite) - wzj_whut的个人空间 - OSCHINA - 中文开源技术交流社区