直接依赖和间接依赖
在项目中直接引入的依赖叫做直接依赖,而那些被动引入的就叫间接依赖
比如上图中,A 是我们的项目,我们在项目中直接引入了 B 模块,所以 B 和 A 的关系就是直接依赖,而 B 工程内部引入了 C,
所以 B 和 C 也是直接依赖关系,如果 B 工程在引入 C 时,指定了 C 模块的依赖范围是 <scope>compile</scope>
,那么 C 模
块就会随着 B 模块一同被引入到我们的工程A 中,这时候 A 和 C 的关系就是间接依赖
依赖冲突
Maven 的依赖冲突,我认为有两种情况,Maven 能自动解决的、需要手动解决的
1. Maven 可以自动解决的依赖冲突
在项目中,不管是直接依赖还是间接依赖,当有多个 <groupId>
、<artifactId>
相同,<version>
不同的依赖引入时,
Maven 就会认为我们引入了相同模块的不同版本,其就会被判定为依赖冲突,这种情况 Maven 会用自己的仲裁机制帮
我们取舍
2. 需要手动解决的依赖冲突
模块间的 <groupId>
、<artifactId>
、<version>
都不相同,但是引入的这些模块中具有相同路径的类(包名+类名
完全相同),这个时候就需要我们自己去解决依赖冲突问题
Maven 的依赖仲裁
依赖仲裁是 Maven 自动解决依赖冲突的手段,我们想更好的利用它,就必须知道其仲裁的规则,其通过 最短路径优先
和 先声明优先
两个依据来判断最终留下的模块
最短路径优先
当项目的依赖树中存在相同模块的不同版本时,Maven 的仲裁机制就会介入,其首先会通过最短路径的方式来对
冲突的模块进行取舍,如下图,假设我们的项目是A,明显C模块发生了依赖冲突,那么按照最短路径优先的原则,
Maven 最后会留下 A → B → C 1.0 这个路径下的 C 模块
先声明优先
当两个依赖冲突的模块,其路径距离相同时,就会使用先声明优先的规则,这个就很简单了,就是留下先声明的模块,
如下图,假设我们的项目是A,两个冲突的模块C到 A 的距离是相同的,这时 Maven 就会根据先声明优先的规则选择
A → B → C 1.0 这个路径下的 C 模块,因为其声明在前
至于什么叫先声明,非常简单,用上图例子,我写个伪代码
<!-- 这个 B 的依赖信息就是先声明的,所以仲裁后会留下B模块中依赖的C模块 -->
<dependency>
<groupId>B</groupId>
<artifactId>B</artifactId>
<version>release</version>
</dependency>
<dependency>
<groupId>D</groupId>
<artifactId