依赖是具有传递性的,程与工程之间也是有依赖关系的。
依赖具有传递性
仔细查看crm-web子工程的结构,此时可以看到,它不仅把crm-service子工程依赖进来了,而且还把crm-dao子工程也依赖进来了,这是因为依赖具有传递性。
如果MakeFriends.jar直接依赖于HelloFriend.jar,而HelloFriend.jar又直接依赖于Hello.jar,那么MakeFriends.jar也依赖于Hello.jar,这就是传递性依赖,只不过这种依赖是间接依赖。
依赖的传递范围
如果crm-dao子工程开发完毕了,那么紧接着就要编写JUnit单元测试用例了。相应地,就要在pom.xml文件中添加JUnit的依赖了,并且scope要置为test。查看crm-dao发现junit-4.9.jar这个jar包确实引入了,这是毋庸置疑的。
crm-service子工程直接依赖于crm-dao子工程,而crm-dao子工程又直接依赖于junit-4.9.jar,由于依赖具有传递性,那么想必crm-service子工程也会依赖于junit-4.9.jar。
并不是这样
查看crm-service子工程的结构,你就知道该工程中并没有引入junit-4.9.jar这个jar包。
为什么呢
其实依赖传递也是有范围的,传递依赖不能无休止的往下面传递下去。
以上表格中的中间部分即是传递依赖的范围,可见传递依赖不是无休止的往下面传递下去的。
依赖传递的两个原则
依赖传递有两个原则,一个是第一声明者优先原则,另一个是路径近者优先原则。下面我会对这两个原则进行详细阐述。
- 第一声明者优先原则
当项目的依赖中,其中有多个依赖同时依赖同一个依赖时,优先使用声明靠前的依赖,即:第一声明者优先原则
<!-- 依赖管理的第一个原则:第一声明者优先原则(谁先声明,谁先用) -->
<!-- 下面这个会引入spring-beans-4.2.2.RELEASE.jar,但是最后生效的只有这个spring-beans-4.2.2.RELEASE版本的jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<!-- 下面这个会引入spring-beans-3.0.5.RELEASE.jar -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>2.3.24</version>
</dependency>
- 路径近者优先原则
<!-- 下面这个会引入spring-beans-4.2.2.RELEASE.jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<!-- 下面这个会引入spring-beans-3.0.5.RELEASE.jar -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>2.3.24</version>
</dependency>
<!-- 依赖管理的第二个原则:路径近者优先原则 -->
<!-- 这个spring-beans-4.2.4.RELEASE版本的jar包放到最后面去了,但是它还是生效了。那这是为啥啊? -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
此时,工程中如果要引入spring-beans,可以有以下方法:
- 通过引入struts2-spring-plugin-2.3.24.jar,它会引入spring-beans-.3.0.5.RELEASE这个版本的jar包,但需要经过的路径为2个节点;
- 通过引入spring-context-4.2.2.RELEASE.jar,它会引入spring-beans-.4.2.2.RELEASE这个版本的jar包,但需要经过的路径也为2个节点;
- 如果直接引入spring-beans-4.2.4.RELEASE.jar,那么只需要经过1个节点。
因此不管spring-beans-4.2.4.RELEASE.jar的位置在哪,工程中始终都是引入spring-beans-4.2.4.RELEASE这个版本的jar包。这就是所谓的路径近者优先原则。