Maven依赖冲突问题

1、maven的作用是什么?
Maven的核心功能便是合理叙述项目间的依赖关系,通俗点讲,就是通过pom.xml文件的配置获取jar包,而不用手动去添加jar包
所以maven的作用就是通过在pom.xml文件中去配置我们要使用的依赖,然后maven会自动去获取jar包,避免手动去找jar包然后导入到项目中。
2、maven怎获取依赖的?
 仓库分为:本地仓库、第三方仓库(私服)、中央仓库
(1)本地仓库:就是我们自己下载的maven,安装目录下的repository目录下面,我们在项目中使用到的jar,如果进行了配置,都会默认存储在这个目录下面
(2)第三方仓库,又称为内部中心仓库,也称为私服
    私服:一般是由公司自己设立的,只为本公司内部共享使用。它既可以作为公司内部构件协作和存档,也可作为公用类库镜像缓存,减少在外部访问和下载的频率。(使用私服为了减少对中央仓库的访问)
    也就是一般公司都会创建这种第三方仓库,保证项目开发时,项目所需用的jar都从该仓库中拿,每个人的版本就都一样。
    注意:连接私服,需要单独配置。如果没有配置私服,默认不使用

(3)中央仓库
就是我们的maven/conf/setting的配置文件中配置的中央仓库镜像,在我们的本地仓库中没有这个jar包时,就会去中央仓库中下载
Maven默认连接的中央仓库是国外的,所以会感觉下载很慢,如果想要快一点,可以自己配置镜像,连接国内的
在项目中,maven默认去本地仓库中获取jar,如果本地没有的话,就去中央仓库中获取
3、我们怎么找到要引入的依赖
https://mvnrepository.com/ 这个网站可以直接帮我们提供依赖怎么写,通过该依赖又依赖了什么jar
如果一个项目中有多个模块,尽量将共同依赖的jar形成一个父依赖,然后子模块中只需要引入依赖,不需要引入依赖的版本,这样可以减少冲突。
4、maven的结构分析

    pom.xml文件目录
<?xml version="1.0" encoding="UTF-8”?>   //指定了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>   //指定了当前POM模型的版本
   <groupId>com.byrobot</groupId>       //定义了项目属于哪个组   
	<artifactId>account</artifactId>     //定义了当前Maven项目在组中唯一的ID
    <version>1.0.0</version>             //制定了项目当前的版本   1.0.0.SNAPSHOT:意为快照,可被更新覆盖
    <name>account</name>                 //声明了一个队用户更为友好的项目名称

<dependencies>
   	<dependency>
      	 <groupId>junit</groupId>  //通过groupId和artifactId找到这个依赖,用于定位的
       <artifactId>junit</artifactId>
       <version>4.11</version>  //引入依赖的版本
       <scope>test</scope>  //依赖范围
       <exclusions> //这个是用来排除引入这个依赖的时候排除某依赖的
 </dependency>
主要是分析一下scope这个标签 这个标签是指定依赖的使用范围 (1)、compile 的范围 当我们在pom.xml文件中的标签中依赖为compile的时候,会在编译的时候将这个依赖加入进来,并且在打包(mvn package)的时候也会将这个依赖加入进去。简单来说就是编译和打包的时候直接加入,其他时候不会加入!对于编译、测试、运行三种classpath都有效 (2)、provided的范围 在编译和测试的时候有效,在执行(mvn package)进行打包jar或者war包的时候不会加入,如果加入会出现包的冲突。 (3)、test的范围 意思是在测试的时候才会真正生效,但是其他的时候就不会,比如单元测试的时候你加入@Test注解时候会自己生效的,不用管它。 (4)、runtime的范围 同理在运行的时候才会依赖,在编译的时候不会依赖啦。。

5、maven中常见问题——依赖冲突
首先我们要知道什么是依赖冲突
依赖冲突是指:一个项目,它直接或者间接的依赖的两个不同版本的依赖,maven选择了其中一个版本,从而导致了因为版本不同而导致的方法找不到或者类找不到的问题
那么,什么叫一个项目直接或间接依赖了两个不同的依赖呢
首先介绍一下传递依赖 。。。
传递依赖的前提
A–>B–>C。当前项目为A,A依赖于B,B依赖于C。知道B在A项目中的scope,那么怎么知道C在A中的scope呢?答案是:
当C是test或者provided时,C直接被丢弃,A不依赖C;
否则A依赖C,C的scope继承于B的scope。
传递依赖的前提是:c的scope不是test或者是provided的,如果是这两种,那么c会直接被抛弃。
举个例子:
在这里插入图片描述

project这个项目直接依赖了spring-core 的4.0.8版本,同时依赖了spring-boot,但是spring-boot直接依赖了spring-core4.3.13版本
,这样这个项目就又间接依赖了spring-core4.3.13版本。所以,一个项目同时依赖了两个不同的版本,那么它就会选择其中一个版本,然后忽略另一个版本
那么,maven是怎么在两个版本中进行选择的呢?
分为两种情况:
(1)同等路径长度:
如果项目A引入了两个依赖a,b:A<-a,b
同时a<-c(版本号为1.1),b<-c(版本号为1.3):表示在依赖a中,使用了依赖c,同时依赖b中也是用了依赖c
这个时候,在项目A使用时,就发生了依赖冲突:因为同时有两个版本的c依赖
如果是同等路径下,我们会哪个写在前面就使用哪一个
(2)非同等路径长度
如果项目A引入了两个依赖a,b:A<-a,b
同时a<-c(版本号为1.1),b<-e<-c(1.3):表示在a中使用了依赖c,同时b中使用了依赖e,而依赖e又使用了依赖c
这样也会造成依赖冲突
因为是非同等路径长度,所以我们直接选用短路径的依赖版本
因为maven选择了其中的一个版本,但是有的依赖使用了另一个版本的方法,恰好这个方法在我们选择的版本中被修改了,或者被抛弃了,那么,就会出现方法找不到的异常
所以并不是说如果一个依赖引用了两个或多个不同版本的相同id的依赖就一定会产生依赖冲突,而是说我们使用到了被忽略/抛弃的版本里面的方法,恰好这个方法在我们选择的这个版本中没有,就会产生依赖冲突

6、发生冲突的时候我们怎么解决
发生冲突时,首先要做的是找到冲突,才能解决,
但是如果靠我们自己去一个一个jar去测是很麻烦的,一般都会依赖工具
这里推荐两种方式
(1)idea自带的,点击右侧的maven-dependency-小图标,idea会自动将pom.xml中的所有依赖变成一颗依赖树,产生冲突的地方会变成红色,你就可以找到冲突发生的位置
(2)maven helper插件
安装了这个插件之后,在pom.xml文件的最下方,就会出现一个dependency analyzer,点击,就会出现冲突
找到冲突之后,就要开始解决冲突
如果A引入的C使用的功能并不跟被抛弃的类或方法有关,而是其他在1.1版本中仍然没有改变的类或方法,那么可以考虑直接使用旧的1.0版本,那么可以使用exclusion标签来在A中排除掉对C的依赖,那么A在使用到C的功能时会使用B引入的1.0旧版本C。即A其实向B妥协使用了B依赖的C。

当然,我只是提供一些方法,自己写的代码也很少,所以在这方面也没有经验,以后只能在项目中不断地练习,如果大家有什么好的解决依赖冲突的方法,可以分享给我,我真的很需要。谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值