maven的依赖特性

maven的依赖特性很多很杂,这里大概总结一下,maven的依赖特性主要是依赖范围和传递依赖,前者会影响后者,这篇文章会介绍传递依赖的传递原则,出现冲突传递依赖默认如何处理,我们自己可以怎么处理等内容

依赖范围

依赖范围会影响传递性依赖,同时也会影响项目构建任务中使用的classpath。

Maven有以下6种依赖范围:

compile
这是默认范围。如果没有指定,就会使用该依赖范围。编译依赖对项目所有的classpath都可用。此外,编译依赖会传递到依赖的项目。
provided
和compile范围很类似,但provided范围表明你希望由JDK或者某个容器提供运行时依赖。例如,当使用Java EE构建一个web应用时,你会设置对Servlet API和相关的Java EE APIs的依赖范围为provided,因为web容器提供了运行时的依赖。provided依赖只对编译和测试classpath有效,并且不能传递。
runtime
runtime范围表明编译时不需要依赖,而只在运行时依赖。此依赖范围对运行和测试classpath有效,对编译classpath无效。
test
test范围表明使用此依赖范围的依赖,只在编译测试代码和运行测试的时候需要,应用的正常运行不需要此类依赖。
system
系统范围与provided类似,不过你必须显式指定一个本地系统路径的JAR,此类依赖应该一直有效,Maven也不会去仓库中寻找它。

mark

传递依赖

传递依赖基于要传递的依赖scope为compile,runtime,system的依赖范围,scope为test和provided不会传递依赖 ,此外传递性依赖的嵌套深度没有任何限制,只是在出现循环依赖时会报错。下图是传递依赖时的scope变化,第一列表示直接依赖,第一行表示间接依赖的Scope

举例说明:
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。

mark

基本传递依赖

传递依赖指的是A依赖B,B依赖C,D,F等,那么A也同时依赖C,D,F

mark

传递依赖冲突-依赖调解

当项目中出现多个版本构件依赖的情形,依赖调解决定最终应该使用哪个版本,主要依赖于两个原则(注意优先第一个原则,两个原则有优先级之分),这是maven自动进行的

  1. 短路径优先原则
    A依赖B工程,B工程依赖C-1.jar,A工程依赖C-2.jar,那么A工程最终依赖的是C-2.jar,因为这条依赖链最短

    mark

  2. 第一声明原则
    A依赖B工程,B工程依赖S-1.jar,A工程依赖C工程,C工程依赖S-2.jar,那么A工程最终依赖的是S-1.jar,因为在依赖链长度相同时,A工程在pom文件中先声明依赖B工程,先声明指的是在A工程pom文件中的dependencies标签下,B工程的dependency写在C工程前面

    mark

    mark

exclusions元素排除依赖

当项目中某个传递依赖我们不需要时可以使用标签进行排除

1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
<exclusions>
<exclusion>
<artifactId>spring</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>

可选依赖-Optional Dependencies

当自己开发一个供别人使用的jar包,项目依赖于多个模块,完成不同功能,各个功能相互独立,那么当第三方使用我的jar包时可以排除他不需要的依赖功能jar包,保留其需要的,这需要”我”在pom中配置依赖的可选性

1
2
3
4
5
6
7
8
<dependency>
<groupId>sample.ProjectB</groupId>
<artifactId>Project-B</artifactId>
<version>1.0</version>
<scope>compile</scope>
<optional>true</optional> <!-- value will be true or false only -->
</dependency>
</dependencies>

假设以上配置是项目A的配置,即:Project-A –> Project-B。在编译项目A时,是可以正常通过的。
如果有一个新的项目X依赖A,即:Project-X -> Project-A。此时项目X就不会依赖项目B了。如果项目X用到了涉及项目B的功能,那么就需要在pom.xml中重新配置对项目B的依赖。

参考

Maven依赖中的scope详解
Maven入门-4.Maven的依赖
《Maven官方文档》-Maven依赖机制简介
可选依赖及排除依赖


-------------本文结束感谢您的阅读-------------