[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是传递性依赖。第一直接依赖的范围和第二直接依赖的范围决定了传递性依赖的范围。

最左边一行表示第一直接依赖范围,最上面一行表示第二直接依赖范围,中间的交叉单元格则表示传递性依赖范围。

  compile test provided runtime
compile compile --- --- runtime
test test --- --- test
provided provided --- provided provided
runtime runtime --- --- runtime

仔细观察上面表格,我们发现这样的规律:

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

来源于:《Maven实战》

时间: 2024-12-23 12:03:12

[Maven实战](9)传递性依赖的相关文章

学习笔记——Maven 如何处理传递性依赖

maven引入的传递性依赖机制,一方面大大简化和方便了依赖声明,另一方面,大部分情况下我们只需要关心项目的直接依赖是什么,而不用考虑这些直接依赖会引入什么传递性依赖.但有时候,当传递性依赖造成问题的时候,我们就需要清楚地知道该传递性依赖是从哪条依赖路径引入的. 例如,项目A有这样的依赖关系 : A-->B-->C-->X(1.0).A-->D-->X(2.0),X是A的传递性依赖,但是两条依赖路径上有两个版 本的X,那么哪个X会被maven解析使用呢?两个版本都被解析显然是不

【Maven】---坐标与依赖

Maven坐标与依赖 最近想深度学习下maven,找到一本书叫<Maven实战>,这本书讲的确实很好,唯一遗憾的是当时maven教学版本是3.0.0的,而目前已经到了3.5.4了,版本存在差距, 没关系,如果有时间和精力我也会阅读官方文档,看看到底有哪些变换. 一.坐标详解 1.何为Maven坐标 maven定义了这样一组规则:世界上任何一个构件都可以使用maven坐标唯一标识,坐标元素包括:groupId.artifactId.version.packaging.classifier.只要提

[Maven实战](8)依赖配置与依赖范围

 1. 依赖配置 依赖基本配置: <project> <dependencies> <dependency> <groupId>...</groupId> <artifactId>...</artifactId> <version>...</version> <exclusions> <exclusion> <groupId>...</groupId>

Maven实战(六)依赖

我们项目中用到的jar包可以通过依赖的方式引入,构建项目的时候从Maven仓库下载即可. 1. 依赖配置    依赖可以声明如下: <project> ... <dependencies> <dependency> <groupId>group-a</groupId> <artifactId>artifact-a</artifactId> <version>1.0</version> <exc

《Maven实战》整理三:坐标和依赖

1.1 何为Maven坐标 正如之前所说的,Maven的一大功能就是管理项目依赖.为了能自动化地解析任何一个Java构件,Maven就必须将它们唯一标识,这就依赖管理的底层基础——坐标. 1.2 坐标详解 Maven坐标的元素包括:groupId,artifactId.version.packaging.classifier.先看一组坐标定义,如下: <groupId>org.sonatype.nexus</groupId> <artifactId>nexus-inde

maven实战第十篇_10_yuocng_依赖

依赖调解: 项目A有这样的依赖关系:A -> B -> C -> X(1.0) , A -> D -> X(2.0) X是A的传递性依赖,但是两条依赖路径上有两个版本的X,那么哪个X会被Maven解析使用呢? 两个版本都解析是不对的,因为那会造成依赖重复,因此必须选择一个. maven依赖调解的第一原则是:路径最近者优先.该例子中X(1.0)的路径长度为3,而X(2.0)的路径长度为2,因此X(2.0)会被解析使用. 但是,比如这样的依赖关系:A -> B  ->

Maven实战07_依赖

1:依赖声明 <project> ... <dependencies> <dependency> <groupId>...</groupId> <artifactId>...</artifactId> <version>...</version> <type>...</type> <scope>...</scope> <optional>.

《Maven实战》笔记-2-坐标和依赖

一.依赖范围 Maven在编译项目主代码的时候,需要使用一套classpath--编译classpath: 在编译和执行测试的时候,使用另一套classpath--测试classpath: 实际运行Maven项目的时候,又会使用一套classpath--运行classpath. [依赖范围]就是用来控制依赖与这三种classpath的关系,Maven有以下几种依赖范围: 1.compile:编译依赖范围 默认,对编译.测试.运行三种classpath都有效,如spring-core. 2.tes

Maven实战(十一)eclipse下载依赖jar包出问题

问题描述 在pom.xml中配置了依赖,但是提示依赖不成功,或在本地仓库找不到相关依赖 大致错误如下: ArtifactDescriptorException: Failed to read artifact descriptor for commons-beanutils:commons-beanutils-core:jar:1.8.0: ArtifactResolutionException: Could not transfer artifact commons-beanutils:com