一个传递性依赖就是对于一个依赖的依赖。如果project-a依赖于project-b,而后者接着依赖于project-c,那么project-c就被认为是project-a的传递性依赖。如果project-c
依赖于project-d
,那么project-d
就也被认为是project-a
的传递性依赖。Maven的部分吸引力是由于它能够管理传递性依赖,并且能够帮助开发者屏蔽掉跟踪所有编译期和运行期依赖的细节。你可以只依赖于一些包如Spring
Framework,而不用担心Spring Framework的所有依赖,Maven帮你自动管理了,你不用自己去详细了解配置。
Maven是怎样完成这件事情的呢?它建立一个依赖图,并且处理一些可能发生的冲突和重叠。例如,如果Maven看到有两个项目依赖于同样的groupId
和artifactId
,它会自动整理出使用哪个依赖,选择那个最新版本的依赖。虽然这听起来很方便,但在一些边界情况中,传递性依赖会造成一些配置问题。在这种情况下,你可以使用依赖排除。
Section 9.4.1, “依赖范围”中提到的每种依赖范围不仅仅影响声明项目中的依赖范围,它也对所传递性依赖起作用。表达该信息最简单的方式是通过一张表来表述,如Table 9.1, “范围如何影响传递性依赖”。最顶层一行代表了传递性依赖的范围。最左边的一列代表了直接依赖的范围。行与列的交叉就是为某个传递性依赖指定的范围。表中的空格意思是该传递性依赖被忽略。
Table 9.1. 范围如何影响传递性依赖
直接范围 | 传递性范围 | |||
---|---|---|---|---|
compile | provided | runtime | test | |
compile | compile | - | runtime | - |
provided | provided | provided | provided | - |
runtime | runtime | - | runtime | - |
test | test | - | test | - |
要阐明传递性依赖范围到直接依赖范围的关系,考虑如下例子。如果project-a
包含一个对于project-b
的测试范围依赖,后者包含一个对于project-c
的编译范围依赖。project-c
将会是project-a
的测试范围传递性依赖。
你可以将这看成是一个作用于依赖范围上的传递性边界。那些已提供范围和测试范围的传递性依赖往往不对项目产生影响。该规则的例外是已提供范围传递性依赖到已提供范围直接依赖还是项目的一个已提供范围依赖。编译范围和运行时范围的传递性依赖通常会影响那个一个项目,无论它的直接依赖范围是什么。编译范围的传递性依赖将会和直接依赖产生与后者相同范围的的结果。运行时范围的传递性依赖也会和直接依赖产生与后者相同范围的结果,除非当直接依赖是编译范围的时候,结果是运行时范围。