首页 >> 大全

【maven】 依赖树(dependency、dependencyManagem

2023-07-07 大全 28 作者:考证青年

文章目录 2. 查看依赖树3. 处理冲突

相关文章:

maven pom.xml详解

maven 依赖树(、)

使用 -boot- 方便管理项目依赖 1. 概述

boot工程示例:


<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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0modelVersion><parent><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-parentartifactId><version>2.5.4version><relativePath/> parent><groupId>com.examplegroupId><artifactId>demoartifactId><version>0.0.1-SNAPSHOTversion><name>demoname><description>Demo project for Spring Bootdescription><properties><java.version>11java.version>properties><modules><module>mall-commonmodule><module>mall-ordermodule>modules><properties><java.version>1.8java.version><spring-cloud.version>Hoxton.SR8spring-cloud.version>properties><dependencies><dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-webartifactId>dependency><dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-testartifactId><scope>testscope>dependency>dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloudgroupId><artifactId>spring-cloud-commonsartifactId><version>${spring-cloud.version}version>dependency>dependencies>dependencyManagement><build><plugins><plugin><groupId>org.springframework.bootgroupId><artifactId>spring-boot-maven-pluginartifactId>plugin>plugins>build>project>

1.1 父pom中的

引用的maven 依赖,默认被其子模块全部依赖,其子模块不用显示引用

优点:所有的子模块,不用再次引用,公用父模块的引用和版本号管理

缺点:子模块引用冗余,对于自己不需要引用的包,也会被引用过来

1.2 父pom中的

父pom通过管理,引用相关maven依赖后,子模块需要再次引用,但是不需要设置版本号。版本号由父pom中的 引用的依赖及版本号统一管理

若子模块中,想单独升级某一个依赖的版本号,则可在子模块中针对某个依赖添加版本号,此时子模块下的那个依赖的版本号会覆盖父pom对该依赖设置的版本号

优点:父pom 统一管理各个依赖的版本号,子模块可以按需要引用自己需要的依赖,灵活设置自己需要的依赖版本号或直接依赖父pom的版本号

缺点:子模块pom中要显示引用自己需要的依赖

2. 查看依赖树

CMD命令行下,进入pom.xml所在的目录,可以是父模块的目录,也可以是子模块的目录,区别在于前者会按子模块分级,展示所有模块的依赖树,后者只查子模块自身相关的依赖树,后者的结果是前者的一个子集。

mvn dependency:tree

mvn dependency:tree >d:/tree.txt

表示按条件过滤,表示显示详细信息,方便处理冲突

mvn :tree - -=[:][:]

括号中的参数是可选项

mvn dependency:tree -Dverbose -Dincludes=org.springframework:spring-tx

3. 处理冲突 3.1 处理冲突的原则

简介:处理jar包依赖冲突,首先,对于多个jar包都引用同一jar包的情况,最好是在程序中显式定义被共同引用的jar包的依赖,来统一版本号,方便维护

如果A和B都依赖同一jar包C,可能会出现两种情况

1.A和B引用的C版本相同

这时按照pom定义顺序选择第一个即可,没有冲突问题,如果在项目的maven中显示定义了C依赖,那么用选择项目定义的依赖,反正都一样,没有影响

2.A和B依赖的C版本不同

选择版本高的那个,这时会出现两种结果

(1) 高版本兼容低版本,所以不会出现问题

(2)高版本不兼容低版本,假如A依赖C2版本,B依赖C3版本,C3不兼容C2,maven选择了高版本C3,对A来说会出现问题

有3种解决方法

[1]提升A版本,找到依赖C3的A版本

[2]如果B版本也可依赖C2,在项目的maven中显示定义对C2的依赖,这样所有都使用C2版本

[3]如果B版本不支持C2版本,只能降低B版本,找到依赖C2的B版本

从功能性和可维护性考虑,高版本提供的功能更多,bug更少,优先考虑1,再考虑2,最后考虑3

3.2 如何处理冲突 3.2.1、maven自动解决依赖冲突的规则是什么?

第一原则:路径最近者优先

项目A有如下的依赖关系:

A->B->C->X(1.0)

A->D->X(2.0)

则该例子中,X的版本是2.0

####第二原则:路径相等,先声明者优先

项目A有如下的依赖关系:

A->B->Y(1.0)

A->C->Y(2.0)

若pom文件中B的依赖坐标先于C进行声明,则最终Y的版本为1.0

3.2.2 如何从依赖树中找到自己预期的版本,是被哪个jar给覆盖了?

先来看个最简单的例子

例1:仅涉及单个工程或模块

slf4j-仅依赖slf4j-api这一唯一的包,前者我们定义1.7.22,但是我们故意把后者单独引入一个1.7.25的高版本

  <!--slf4j-log4j12 ,slf4j-api 均是直接引入--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.22</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.25</version></dependency>

下面是依赖树日志:

[INFO] +- org.slf4j:slf4j-log4j12:jar:1.7.22:compile
[INFO] |  +- (org.slf4j:slf4j-api:jar:1.7.22:compile - omitted for conflict with 1.7.25)
[INFO] |  \- log4j:log4j:jar:1.2.17:compile
[INFO] \- org.slf4j:slf4j-api:jar:1.7.25:compile

for 一般是指存在2个版本有冲突,至少出现一次直接引用(个人总结的,也不一定对,比如如果没有一个直接引入的,但是有2个间接引入的,会有该关键词出现吗?)。这个例子slf4j-和slf4j-api都是直接引入的。

插件也能方便的帮助我们查看依赖树,切换pom.xml至 标签页

扩展知识,怎么知道slf4j-会有个默认依赖的slf4j-api?

原因是每个jar自身也是有pom.xml的,我们查看本地仓库的slf4j-

例如 D:\maven\repo\org\slf4j\slf4j-\1.7.22\slf4j--1.7.22.pom,里面有如下配置:

 <dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><type>test-jar</type><version>${project.version}</version><scope>test</scope></dependency>

现在一目了然,一层层的依赖就是这么来的。

例2:涉及父子模块

在查看依赖树之前我们先来了解一下的用法。

在包含父子项目中,允许在顶层的POM文件中,定义元素。通过它元素来管理jar包的版本,让子项目中引用一个依赖而不用显示的列出版本号。Maven会沿着父子层次向上走,直到找到一个拥有元素的项目,然后它就会使用在这个元素中指定的版本号。

在父模块中定义了org.slf4j为高版本1.7.25,子模块中定义了slf4j-为低版本1.7.22

/pom.xml

<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>my</groupId><artifactId>myParent</artifactId><version>0.0.1-SNAPSHOT</version><!--父模块类型为pom  --><packaging>pom</packaging><modules><!--定义子模块  --><module>mychild</module></modules><dependencyManagement><!-- 这样做的好处:统一管理项目的版本号,确保应用的各个项目的依赖和版本一致 --><dependencies><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.25</version></dependency></dependencies></dependencyManagement>

/pom.xml

  <parent><groupId>my</groupId><artifactId>myParent</artifactId><version>0.0.1-SNAPSHOT</version></parent><groupId>mychild</groupId><artifactId>mychild</artifactId><dependencies>
<!--直接引入slf4j-log4j12,但是间接引入slf4j-api--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.22</version></dependency></dependencies>

依赖树

 \- org.slf4j:slf4j-log4j12:jar:1.7.22:compile+- org.slf4j:slf4j-api:jar:1.7.25:compile (version managed from 1.7.22)\- log4j:log4j:jar:1.2.17:compile

与例1相比,这里只有slf4j-作直接引入,slf4j-api是间接引入。

里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且和scope都读取自父pom。

例3

本例基于例2,注意把slf4j-api也改为直接引入

/pom.xml

	<dependencies><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.22</version></dependency><!--与例2 相比,新增了直接引入slf4j-api--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.22</version></dependency></dependencies>

[INFO] +- org.slf4j:slf4j-log4j12:jar:1.7.22:compile
[INFO] |  +- (org.slf4j:slf4j-api:jar:1.7.25:compile - version managed from 1.7.22; omitted for conflict with 1.7.22)
[INFO] |  \- log4j:log4j:jar:1.2.17:compile
[INFO] \- org.slf4j:slf4j-api:jar:1.7.22:compile

例4

本例基于例2,额外间接引用slf4j-api,总共有2次额外引用

/pom.xml

	<!-- 间接引用slf4j-api --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.22</version></dependency><!-- 新增间接引用slf4j-api --><dependency><artifactId>kafka-clients</artifactId><groupId>org.apache.kafka</groupId><version>2.1.1</version></dependency>

依赖树:

 +- org.slf4j:slf4j-log4j12:jar:1.7.22:compile|  +- org.slf4j:slf4j-api:jar:1.7.25:compile (version managed from 1.7.22)|  \- log4j:log4j:jar:1.2.17:compile\- org.apache.kafka:kafka-clients:jar:2.1.1:compile+- com.github.luben:zstd-jni:jar:1.3.7-1:compile+- org.lz4:lz4-java:jar:1.5.0:compile+- org.xerial.snappy:snappy-java:jar:1.1.7.2:compile\- (org.slf4j:slf4j-api:jar:1.7.25:compile - version managed from 1.7.22; omitted for duplicate)

参考文章《maven冲突》

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了