如下面,一个典型的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>
来源:https://www.cnblogs.com/ranyabu/p/12240637.html