Maven依赖传递和冲突解决
Posted ranyabu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Maven依赖传递和冲突解决相关的知识,希望对你有一定的参考价值。
如下面,一个典型的Maven依赖配置格式。
<dependencies>
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version>版本</version>
<type>依赖的类型,对应于项目的packing,默认是jar</type>
<scope>依赖范围</scope>
<systemPath>配合scope=system时使用</systemPath>
<optional>标记是否为可选依赖</optional>
<exclusions>
用来排除传递性依赖
<exclusion>
</exclusion>
</exclusions>
</dependency>
</dependencies>
今天想到Maven的依赖传递,和冲突的解决尚有疑惑,比如scope的如何决定依赖传递,冲突时maven的默认解决是什么,如何调节?
依赖范围
Maven的依赖范围一共有:
- compile,默认,对于编译、测试、运行范围有效
- runtime,对运行范围有效,典型如JDBC类库这种接口与实现项分离的类库,在编译时仅依赖相关的接口,在具体运行时,才需要具体的mysql/oracle等驱动程序
- privoded,对编译、测试范围有效;典型的如servlet-api,运行时由容器提供
- system,与provided一样,但必须显示指定依赖文件,通过
test,对测试范围有效
import,不对任何范围有效,只能在dependencyManagement中使用
依赖传递
compile | runtime | provided | test | |
---|---|---|---|---|
compile | compile | runtime | - | - |
runtime | runtime | runtime | - | - |
provided | provided | provided | provided | - |
test | test | test | - | - |
每个不同的作用范围以不同的方式影响依赖传递。如上面表格以A项目为例:
左列为 A->B(compile)第一关系(直接依赖):A依赖B compile
横列为 B->C(compile)第二关系(传递依赖):B依赖C compile
交叉即最终的传递性依赖范围,未列出的将被忽略。
依赖冲突
依赖传递,必然会出现依赖冲突,冲突调节有两个原则:
最短路径原则
比如A->B->C-D(1.0),A-C-D(2.0),则选择D(2.0)
最先声明原则
比如A->B->D(1.0),A-C-D(2.0),则选择D(1.0)
可以自己使用mvn dependency:tree
命令试试,idea用户直接使用Maven Helper
插件。
对于冲突的解决,可以手动介入,使用exclusions一个个解决冲突的jar
<dependency>
<groupId>sample.ProjectB</groupId>
<artifactId>Project-B</artifactId>
<version>1.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>sample.ProjectE</groupId> <!-- Exclude Project-E from Project-B -->
<artifactId>Project-E</artifactId>
</exclusion>
</exclusions>
</dependency>
依赖管理
项目中使用Springboot有两种方式,
一种是使用继承父类
,
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.11.RELEASE</version>
</parent>
另一种则是使用了dependencyManagement
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.11.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
这两种都可以限定当前项目和子项目使用既定的版本,因此依赖时不需要指定version
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>
以上是关于Maven依赖传递和冲突解决的主要内容,如果未能解决你的问题,请参考以下文章