通过maven构建的java项目,各依赖的版本是如何确定的?

我在java项目中使用maven管理依赖。其中借助依赖工具查看,commons-codec的版本是1.16.0。
最终构建出来的jar包中也是1.16.0版本。
image.png

但是我通过idea自带的依赖分析工具查看,commons-codec有两个来源,根据颜色,1.16.0版本应该是是在poi中指定的
image.png
但是poi-4.1.2中指定的却是1.13版本
image.png
我又查看了httpclient中的配置,是1.9版本的commons-codec。这里是因为httpclient是继承自httpcomponents-client,httpcomponents-client中配置了1.9
image.png
所以我想知道为什么最终是1.16版本的commons-codec

阅读 1.5k
2 个回答
✓ 已被采纳

Maven依赖决策

只有两个原则:

  1. 最短路径优先
  2. pom中先声明的优先

比如你问题中的commons-codec(大概举例,没太看清楚)
路径1:kc-common-->aliyun-sdk-oss-->http-client-->commons-codec
路径2:kc-common-->poi-ooxml-->poi-->commons-codec

你这两个路径长短一样,就会看aliyun-sdk-osspoi-ooxmlkc-common中的声明顺序,目前大概率是aliyun-sdk-oss在前

version问题

httpcomponents-client中配置了1.9
poi-4.1.2中指定的是1.13版本
最终是1.16.0

1.看你的pom是不是有<parent>标签,比如声明了spring-boot-parent,这里面会声明 version,会将整个项目中依赖的version全部统一为声明的版本
2.如果有<parent>标签,并且声明的version不是1.16.0,那你看自己的pom中是不是写了<properties>定义,覆盖了<parent>中的version,会以你定义的为准
3.查看当前pom是不是声明了<dependencyManagement>统一管理了version
4.是否使用了三方的bom来管理了版本,三方bom依赖会定义一系列version来统一版本
5.如果有多个bom对同一个库进行了版本管理,先声明的版本会统一整个项目的版本

确定version

1.你可以在idea安装Maven Helpher插件,通过Dependency Analyzer标签的All Dependencies as Tree来查看红色的依赖
2.在项目启动类main里写某个Jar里面具体的一个类,import进去,点击到源码,点击Project栏,点击Select Opened File就可以确定运行时具体决策的jar是哪个版本

依赖管理有多种方案,java采用的是扁平化依赖管理方案,也就是所有的依赖最终会被拉平。例如依赖树如下:

.
`-- A
    `-- D
    `-- C (v1)
`-- B
    `-- C (v2)

最终所有依赖被拉平:

.
`-- A
`-- B
`-- C (v2)
`-- D

多个依赖版本如果冲突,则高版本覆盖低版本,称为版本覆盖。

当然扁平化依赖管理并非唯一依赖解决方案,nodejs采用树形依赖+扁平依赖结合。版本相同则扁平化节省空间,版本冲突则树形依赖

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题