• 【Maven实战】传递性依赖的问题


    在上一篇文章中我们已经介绍了依赖性,这次我们再来介绍下传递依赖的问题,首先我们还是在上篇文章基础之上进行编写。

    1、上篇文章中已经建立了一个user-core的模块,现在首先再建立一个user-log的模块,在此模块中引入log4j、commons-logging等包:

     1 <dependencies>
     2         <dependency>
     3             <groupId>junit</groupId>
     4             <artifactId>junit</artifactId>
     5             <version>4.10</version>
     6             <scope>test</scope>
     7         </dependency>
     8         <dependency>
     9             <groupId>log4j</groupId>
    10             <artifactId>log4j</artifactId>
    11             <version>1.2.11</version>
    12         </dependency>
    13         <dependency>
    14             <groupId>commons-logging</groupId>
    15             <artifactId>commons-logging</artifactId>
    16             <version>1.1.3</version>
    17         </dependency>
    18     </dependencies>

    注意我们这里使用的log4j的版本和在user-core中使用的log4j的版本号是不同的哦。

    为了方便我们在user-log中定义了一个Log类如下:

    1 package com.lq.wangzhen.user.log;
    2 
    3 public class Log {
    4 
    5     public void print(String str){
    6         System.out.println("hello:"+str);
    7     }
    8 }

    user-log的结构图如下:

     2、下面再建立一个项目user-dao模块,在这个模块中我们要对user类进行操作,所以要导入user-core模块:

     1 <dependencies>
     2         <dependency>
     3             <groupId>junit</groupId>
     4             <artifactId>junit</artifactId>
     5             <version>3.8.1</version>
     6             <scope>test</scope>
     7         </dependency>
     8         <dependency>
     9             <groupId>com.lq.wangzhen.user</groupId>
    10             <artifactId>user-core</artifactId>
    11             <version>0.0.1-SNAPSHOT</version>
    12         </dependency>
    13     </dependencies>

    此时我们并没有在user-dao用引入hibernate的jar包,只是引用了user-core,但是我们也在user-dao中发现了hibernate的jar包,这个就是传递性依赖

    对于传递性依赖这里再做一点解释,就是这里user-core依赖于hibernate,而user-dao依赖于user-core,所以user-dao也会依赖于hibernate,这种依赖我们成为是基于compile的依赖,这个是通过scope进行配置的,我们可以在junit依赖中都配置了scope属性,如果此属性没有配置的话,则默认的是compile范围的,而对于scope为test类型的话,则不会进行传递依赖,比如下载我们把user-dao中依赖的junit去掉,如下:

    1 <dependencies>
    2         <dependency>
    3             <groupId>com.lq.wangzhen.user</groupId>
    4             <artifactId>user-core</artifactId>
    5             <version>0.0.1-SNAPSHOT</version>
    6         </dependency>
    7     </dependencies>

    此时只依赖了user-core,而user-core中依赖了junit,如下:

     1 <dependencies>
     2         <dependency>
     3             <groupId>junit</groupId>
     4             <artifactId>junit</artifactId>
     5             <version>4.10</version>
     6             <scope>test</scope>
     7         </dependency>
     8         <dependency>
     9             <groupId>org.hibernate</groupId>
    10             <artifactId>hibernate-core</artifactId>
    11             <version>4.2.5.Final</version>
    12         </dependency>
    13         <dependency>
    14             <groupId>log4j</groupId>
    15             <artifactId>log4j</artifactId>
    16             <version>1.2.17</version>
    17         </dependency>
    18         <dependency>
    19             <groupId>mysql</groupId>
    20             <artifactId>mysql-connector-java</artifactId>
    21             <version>5.1.26</version>
    22         </dependency>
    23     </dependencies>

    但是我们可以发现在其中配置了scope属性为test,所以不会发生传递依赖,即我们的user-dao项目中不会有junit的jar包:

    可以发现其中并没有junit的jar包。

    3、现在再让user-dao项目依赖user-log项目:

     1 <dependencies>
     2         <dependency>
     3             <groupId>com.lq.wangzhen.user</groupId>
     4             <artifactId>user-core</artifactId>
     5             <version>0.0.1-SNAPSHOT</version>
     6         </dependency>
     7         <dependency>
     8             <groupId>com.lq.wangzhen.user</groupId>
     9             <artifactId>user-log</artifactId>
    10             <version>0.0.1-SNAPSHOT</version>
    11         </dependency>
    12     </dependencies>

    因为我们在user-core和user-log中都使用了log4j,并且user-core中使用的是1.2.17版本的,而user-log中使用的是1.2.11版本的,那此时在user-dao中最终会引用那个版本的呢?

    我们可以看到引用的是user-core中的1.2.17版本的,这是为什么呢?此时我们把在user-dao中依赖user-core和user-log的顺序给调换一下,如下:

     1 <dependencies>
     2         <dependency>
     3             <groupId>com.lq.wangzhen.user</groupId>
     4             <artifactId>user-log</artifactId>
     5             <version>0.0.1-SNAPSHOT</version>
     6         </dependency>
     7         <dependency>
     8             <groupId>com.lq.wangzhen.user</groupId>
     9             <artifactId>user-core</artifactId>
    10             <version>0.0.1-SNAPSHOT</version>
    11         </dependency>
    12     </dependencies>

    此时再观察结果:

    此时我们可以看出这里引用的是user-log中的1.2.11版本的log4j,此时我们似乎明白了,在user-dao中先引用的是哪个项目就会使用此项目中的jar包,如果jar包有冲突的话。

    4、到此,我们在以上项目的基础上再建立一个maven项目,命名为user-services,在此项目中依赖于user-dao,user-log,如下:

     1 <dependencies>
     2         <dependency>
     3             <groupId>junit</groupId>
     4             <artifactId>junit</artifactId>
     5             <version>3.8.1</version>
     6             <scope>test</scope>
     7         </dependency>
     8         <dependency>
     9             <groupId>com.lq.wangzhen.user</groupId>
    10             <artifactId>user-dao</artifactId>
    11             <version>0.0.1-SNAPSHOT</version>
    12         </dependency>
    13         <dependency>
    14             <groupId>com.lq.wangzhen.user</groupId>
    15             <artifactId>user-log</artifactId>
    16             <version>0.0.1-SNAPSHOT</version>
    17         </dependency>
    18     </dependencies>

    此时先引用了user-dao,而在user-dao中先引用了user-core,所以user-dao中的log4j的版本是1.2.17版本的,而user-log中的log4j是1.2.11版本的,此时user-services中的log4j是哪个版本呢?我们看图:

    这里发现引用的是1.2.11版本,这是为什么呢?我们明明是先引用的user-dao,而user-dao中的是1.2.17版本的,为什么是这个版本呢?这是因为:

    user-core依赖于log4j 1.2.17

    user-log依赖于log4j 1.2.11

    user-dao依赖于user-core和user-log,最终依赖于log4j 1.2.17

    user-services依赖于user-dao和user-log,此时从user-services找到log4j需要经过user-dao、user-core,需要两步,而从user-log找到log4j只需要一步,所以最终会选择user-log中的log4j,这是maven中的最小路径问题。那么这个选择我们能不能控制呢?当然!我们可以修改user-services中的pom.xml,在依赖于user-log时排除对log的依赖,如下:

     1 <dependencies>
     2         <dependency>
     3             <groupId>junit</groupId>
     4             <artifactId>junit</artifactId>
     5             <version>3.8.1</version>
     6             <scope>test</scope>
     7         </dependency>
     8         <dependency>
     9             <groupId>com.lq.wangzhen.user</groupId>
    10             <artifactId>user-dao</artifactId>
    11             <version>0.0.1-SNAPSHOT</version>
    12         </dependency>
    13         <dependency>
    14             <groupId>com.lq.wangzhen.user</groupId>
    15             <artifactId>user-log</artifactId>
    16             <version>0.0.1-SNAPSHOT</version>
    17             <exclusions>
    18                <exclusion>
    19                    <groupId>log4j</groupId>
    20                    <artifactId>log4j</artifactId>
    21                </exclusion>
    22             </exclusions>
    23         </dependency>
    24     </dependencies>

    这样user-services就会依赖于user-dao中的log4j了。

  • 相关阅读:
    del:根据索引值删除元素
    Python insert()方法插入元素
    Python extend()方法添加元素
    Python append()方法添加元素
    Python list列表添加元素的3种方法
    什么是序列,Python序列详解(包括序列类型和常用操作)
    Python运算符优先级和结合性一览表
    Python print()函数高级用法
    Python input()函数:获取用户输入的字符串
    Python变量的定义和使用
  • 原文地址:https://www.cnblogs.com/wukong65/p/3321756.html
Copyright © 2020-2023  润新知