上篇介绍了Maven坐标,今天带大家了解一下传递依赖。在了解传递依赖之前,我们需要了解一下依赖范围:
compile:编译依赖范围,在编译,测试,运行时都需要。若不指定编译范围,则默认compile。
test: 测试依赖范围,测试时需要。编译和运行不需要。如Junit
runtime: 运行时依赖范围,测试和运行时需要。编译不需要。如JDBC驱动包
provided:已提供依赖范围,编译和测试时需要。运行时不需要。如servlet-api
system:系统依赖范围。本地依赖,不在maven中央仓库。
传递依赖:
即:A依赖B 且 B依赖C 则 A可传递依赖到C(A——>B B——>C => A——>C)
若无传递依赖,当A需要依赖B,而B需要依赖C,则A需要引入C,才能保证不出错。这就需要我们不仅考虑当前需要引用什么jar包,还要考虑引用的jar包需要依赖什么,这样就容易导致因缺少jar包而报错,或引用了多余的无用jar包......现有了Maven的传递依赖,我们便不用考虑B的依赖,也不用担心引入了多余的依赖。Maven会解析各个直接依赖的POM,将那些必要的间接依赖,以传递依赖的形式引入到当前的项目中。
传递依赖的依赖范围:
第一列理解为A——>B
第一行理解为B——>C
举例理解该表:
依赖范围用<scop>标签声明。
若A——>B声明的依赖范围为test(第二行)
若B——>C声明的依赖范围为compile(第一列)
则传递依赖的结果A——>C的依赖范围为test。
依赖路径:
如:A->B->C->D(1.0)/A->E->D(2.0),D是A的传递性依赖,但有两条路径。这时Maven会根据依赖调解的第一原则:路径最近者优先。所以该例中D(2.0)被解析使用。
但若路径长度相同,Maven该如何抉择呢,如:A->B->D(1.0)/A->E->D(2.0)。则此时Maven会根据依赖调解的第二原则:第一声明者优先(POM中依赖声明的顺序)。则该例中D(1.0)被解析使用。
除此还有可选依赖,可选依赖不传递。
可选依赖用<optional>true</optional>声明。带有此标签的jar包不被传递依赖。
总结:
Maven引入的传递依赖机制,一方面大大简化和方便了依赖声明,另一方面,大部分情况下我们只需要关心项目的直接依赖是什么,而不用考虑这些直接依赖会引入什么传递性依赖。