依赖包含的元素
1、groupid
2、artifactid
3、version
4、type : 依赖的类型,对应于项目坐标定义的packaging
5、scope: 依赖范围(三种classpath: 编译、测试、运行)
compile: 编译范围,对编译、测试和运行都有效
test: 测试范围, 只对测试有效 (例子:Junit)
provided: 对编译和测试有效,对运行无效(例子:servlet api)
runtime: 对测试和运行有效,对编译无效(例子:jdbc)
system: 对编译、测试和运行的范围影响同provided, 但是这个与系统绑定,可移植性不高,
在配置时需要通过systemPath元素来指定依赖的路径。
import: 对编译、测试和运行基本无影响;用于一个dependencyManagement对另一个dependencyManagement的继承
6、optional : 标记依赖是否可选
7、exclusions: 排除传递依赖
传递依赖
举一个例子,A依赖B(compile),B依赖C(compile),那么A对于B是第一直接依赖,B对于C是第二直接依赖,A对于C是传递依赖(compile)。
第一直接依赖和第二直接依赖的范围直接影响传递依赖的范围:
有规律的:
第二直接依赖为compile的,传递依赖与第一直接依赖相同
第二直接依赖为test的,传递依赖不可用
第二直接依赖为provided,只传递第一直接依赖为provided的,且传递依赖为为provided
第二直接依赖为runtime, 传递依赖与第一直接依赖里除了compile的依赖相同,第一直接依赖为compile的传递依赖为runtime.
依赖调解
为了解决重复依赖的问题,maven有依赖调解机制
依赖调解的二个原则:
1、最短路径优先; A->B,B->C,C->X(1.0); A->B,B->X(2.0), X(2.0)将被解析使用
2、第一申明者优先;路径长度相同,谁先申明用谁的。
可选依赖
可选依赖无法传递。一般情况下不应该使用可选依赖,面向对象的单一职责原则,同样适用与maven。例子就不举了。
最佳实践
通过:
mvn dependecy:list ->已经解析的依赖
mvn dependecy:tree ->依赖关系树
mvn dependecy:analyze ->使用但是未申明 和 申明但是未使用 两种情况
来分析项目的的依赖排查问题