文章目录
- 基本背景
- 基本排查冲突工具
- 依赖传递:很多依赖到底使用哪个版本的依赖
- dependencyManagement 作用
- exclusions
- 其他问题
基本背景
你使用 java,使用 maven pom.xml 管理你的依赖包
可能常常遇到依赖版本冲突,或者很多依赖包,不清楚到底使用哪个依赖的版本
基本排查冲突工具
idea 可以下载 mavenHelper 插件,可以很方便来做依赖冲突的排查
原始的可以使用 mvn 命令
mvn dependency:tree -Dverbose
依赖传递:很多依赖到底使用哪个版本的依赖
比如 A 项目中使用 B 依赖,B 项目中使用了 C 依赖,
再同时 A 项目中使用了 D 依赖,D 项目中使用了 C 依赖,
再同时 A 项目中使用了 E 依赖,E 项目中使用了 F 依赖,F 项目中使用了 C 依赖
再同时 A 项目中使用了 C 依赖
即:
- A -> B -> C(1.0)
- A -> D -> C(2.0)
- A -> E -> F -> C(3.0)
- A -> C(4.0)
那么 A 项目 run 起来后代码逻辑到底使用哪个版本的 C 依赖在跑呢?
首先得明确,并不是 A 自己的代码逻辑使用 4.0 的 C,然后 A 项目中运行到 B 中的代码时候就按照 1.0 的 C 去跑,并不是这样的,统一在 runing 的 A 项目统一使用一个版本的 C 的依赖在 run
依赖传递规则:
- 路径浅的优先级高
- 同层路径的谁先声明谁优先级高
所以按照这样的规则我们知道:
C(4.0) > C(1.0) > C(2.0) > C(3.0)
所以 A 项目将使用 4.0 的 C 在 run
dependencyManagement 作用
同样的例子:
- A -> B -> C(1.0)
- A -> D -> C(2.0)
- A -> E -> F -> C(3.0)
- A -> C(4.0)
如果你设立了 dependencyManagement 中,指定了 C 的版本是 5.0,当 A 不存在直接声明的依赖 C(4.0) 时,它将统一按照 C(5.0) 的版本去 run,如果 A 直接声明了 C 的版本,则优先级最高的是 A 直接声明的 C 的版本
所以优先级上:
A 直接声明的版本 > dependencyManagement 指定的版本 > 路径更浅的依赖版本 > 同深浅则是率先声明的依赖版本
exclusions
依赖中 exclusions 掉某个子依赖,目的是防止内部依赖往外部传递,比如 A -> B,B 项目中有 C 依赖,如果 A 没有直接的 C 依赖,那么 A 使用的是 B 中的 C 依赖的版本,当 B exclusion 掉了 C,则表示这个 C 依赖无法传递到 A
其他问题
依赖隔离?
如果 A -> B -> C,同时也有 A -> C,我想让 A 在 run 时候,A 使用自己的 C 依赖版本,run 到代码 B 到地方使用 B 内部依赖 C 的版本,这样一般是不可行的,如果非要做则使用 Maven Shade 插件来重定位依赖。这样其实做起来比较麻烦