首页 > 代码库 > [Maven实战](9)传递性依赖

[Maven实战](9)传递性依赖

了解Spring的朋友都知道。创建一个Spring Framework项目都须要依赖什么样的Jar包。假设不使用Maven,那么在项目中就须要手动下载相关的依赖。因为Spring Framework又会依赖与其它开源类库,因此实际中往往会下载Spring Framework的jar包。还的下载全部它依赖的其它jar包。

这么做往往就引入了非常多不必要的依赖。还有一种做法是仅仅下载Spring Framework的jar包。不包括其它的相关依赖,到实际使用的时候。再依据报错信息。或者查询相关文档,增加须要的其它依赖。

这么做让我们非常不舒服。


1. 传递性依赖

Maven的传递性依赖机制能够非常好的解决这一问题。我们还是以HelloWorld项目为例。

我们能够从Eclipse创建Spring-HelloWorld项目过程与Maven创建Spring-HelloWorld项目过程看出区别来:


(1)Eclipse创建Spring-HelloWorld项目:
对于使用Spring2.xxx,我们须要下载spring-2.5.6.jar;对于Spring3.xxx,我们须要下载spring-context-4.2.4.RELEASE.jar。spring-core-4.2.4.RELEASE.jar。

除此之外,我们还的下载Spring Framework所依赖的其它的jar:commons-logging-1.2.jar。

(2)Maven创建Spring-HelloWorld项目:
可是使用Maven方式我们仅仅须要知道Sring Framework的jar就可以。不须要知道其所须要commons-logging等jar包。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sjf.springdemo</groupId>
<artifactId>springdemo-helloworld</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springdemo-helloworld</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
</dependency>
</dependencies>
</project>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
 
<groupId>com.sjf.springdemo</groupId>
<artifactId>springdemo-helloworld</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
 
<name>springdemo-helloworld</name>
<url>http://maven.apache.org</url>
 
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
 
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
</dependencies>
</project>

其以上代码是项目配置的依赖,从上面能够看出我们仅仅依赖了Spring Framework的jar,并没有依赖commons-logging。
可是我们从Maven项目上看到Maven的依赖:

Spring2.xxx
技术分享

技术分享
Spring3.xxx
技术分享
技术分享

从上面能够看出我们尽管仅仅依赖了Spring Framework的jar,并没有依赖其它类库的jar,可是项目还是出现了其它的jar。这就是传递性依赖的作用。


下图是上面实例项目的依赖演示图:

技术分享技术分享

那究竟什么是传递性依赖呢?

传递性依赖是在maven2中加入的新特征,这个特征的作用就是你不须要考虑你依赖的库文件所须要依赖的库文件,可以将依赖模块的依赖自己主动的引入。
比如我们依赖于spring的库文件,可是spring本身也有依赖。假设没有传递性依赖那就须要我们了解spring项目依赖,自己加入到我们的项目中。


有了传递性依赖机制,在使用Spring Framework的时候就不用去考虑它依赖了什么,也不用操心引入多余的依赖。Maven会解析各个直接依赖的POM。将那些必要的间接依赖,以传递性依赖的形式引入到当前的项目中。

2.传递性依赖与依赖范围

依赖范围不仅能够控制依赖与三种classpath的关系,还对传递性依赖产生影响。

上面样例中。springdemo-helloworld对于spring-core的依赖范围是compile,spring-core对于commons-logging的依赖范围是compile,那么springdemo-helloworld对于commons-logging这一传递性依赖的范围也就是compile。

如果A依赖于B。B依赖于C。我们说A对于B是第一直接依赖,B对C是第二直接依赖,A对于C是传递性依赖第一直接依赖的范围第二直接依赖的范围决定了传递性依赖的范围


最左边一行表示第一直接依赖范围。最上面一行表示第二直接依赖范围。中间的交叉单元格则表示传递性依赖范围。
 compiletestprovidedruntime
compilecompile------runtime
testtest------test
providedprovided---providedprovided
runtimeruntime------runtime

细致观察上面表格,我们发现这种规律:

  • 当第二直接依赖的范围是compile的时候。传递性依赖的范围与第一直接依赖的范围一致
  • 当第二直接依赖的范围是test的时候,依赖不会得以传递
  • 当第二直接依赖的范围是provided的时候,仅仅传递第一直接依赖的范围也为provided的依赖,切传递性依赖的范围相同为provided
  • 当第二直接依赖的范围是runtime的时候,传递性依赖的范围与第一直接依赖的范围一致,但compile例外,此时传递性依赖的范围为runtime





来源于:《Maven实战》




[Maven实战](9)传递性依赖