(二)依赖传递

一、依赖传递(Scope取值)

        maven认为,程序对外部的依赖会随着程序的所处阶段和应用场景而变化,所以maven中的依赖关系有作用域(scope)的限制。在maven中,scope包含如下的取值:

  •         compile(编译范围)

            compile是默认的范围;如果没有提供一个范围,那该依赖的范围就是编译范围。
            编译范围依赖在所有的classpath中可用,同时它们也会被打包。

  比如:A工程依赖B工程,而B工程中依赖a.jar(scope="compile"),则在A工程中也会自动引入a.jar,这就是scope="compile"的依赖传递。

  •        provided(已提供范围)

            provided依赖只有在当JDK或者一个容器已提供该依赖之后才使用。

    开发时使用,但是运行的时候不需要,因为容器(tomcat)有,如果再引入则会造成包冲突,但是在工程中又不得不引入(不引入则无法开发)  

  比如:web开发中使用的HttpServlet这个jar包,开发的时候必须使用,但是把项目发布到tomcat时候是不能把这个包也引入的(tomcat已经有这个包,再引入可能会冲突)

这时候把这个HttpServlet包的scope="provided",这个当工程被打包的时候这个HttpServlet包不会被打包。
          

  •         runtime(运行时范围)

            runtime依赖在运行和测试系统的时候需要,但在编译的时候不需要。
            比如,你可能在编译的时候只需要JDBC API JAR,
            而只有在运行的时候才需要JDBC驱动实现。

  •        test(测试范围)

            test范围依赖 在一般的 编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用。 测试范围依赖在之前的中介绍过。

  •         compile/runtime:会进行依赖传递

  •         provided/test:     不进行依赖传递。

 二、案例

  • A->B(compile)     第一关系: a依赖b   compile
  • B->C(compile)     第二关系: b依赖c   compile
  • 当在A中配置
<dependency>  
            <groupId>com.B</groupId>  
            <artifactId>B</artifactId>  
            <version>1.0</version>  
</dependency> 

则会自动导入c中的包。关系传递如下表:

第一          第二

compile

test

provided

runtime

compile

compile

-

-

runtime

test

test

-

-

test

provided

provided

-

provided

provided

runtime

runtime

-

-

runtime

  • 依赖冲突的调节

  A->B->C->X(1.0)

  A->D->X(2.0)

由于只能引入一个版本的包,此时Maven按照最短路径选择导入x(2.0)

  A->B->X(1.0)

  A->D->X(2.0)

路径长度一致,则优先选择第一个,此时导入x(1.0)

  • 排除依赖

   A:排除依赖管理

  • 案例

   maven01/pom.xml :

    <dependencies>

        <dependency>
            <groupId>com.shyroke</groupId>
            <artifactId>maven02</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                        <groupId>com.shyroke</groupId>
            <artifactId>maven01</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>

            <groupId>com.shyroke</groupId>
            <artifactId>maven02_1</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

    </dependencies>

  可知,maven01依赖maven02和maven02_1,其中maven02和maven02_1分别依赖:

maven02/pom.xml:

<dependencies>
        <dependency>
            <groupId>com.shyroke</groupId>
            <artifactId>maven01</artifactId>
            <version>3.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

maven02_1/pom.xml:

 <dependencies>
         <dependency>
            <groupId>com.shyroke</groupId>
            <artifactId>maven01</artifactId>
            <version>1.0.1-SNAPSHOT</version>
        </dependency>
  </dependencies>

结果:

如果没有用<exclusions>排除依赖,那么这里引用的是maven02/pom.xml中的依赖(路径长度一致,则优先选择第一个)

  B、在pom.xml中指定具体引用的版本。

    <dependencies>

        <dependency>
            <groupId>com.shyroke</groupId>
            <artifactId>maven02</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        
        <dependency>
            <groupId>com.shyroke</groupId>
            <artifactId>maven02_1</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        
        <dependency>
            <groupId>com.shyroke</groupId>
            <artifactId>maven01</artifactId>
            <version>2.0.1-SNAPSHOT</version>
        </dependency>
        

    </dependencies>

结果:

  • 依赖关系的查看

cmd进入工程根目录,执行  mvn dependency:tree会列出依赖关系树及各依赖关系

 mvn dependency:analyze    分析依赖关系

  • 可以将Spring的版本定义为一个变量。然后在dependency中引用变量的值。
     
      <properties>
            <spring-version>4.3.0.RELEASE</spring-version>
        </properties>
<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring-version}</version>
    </dependency>
原文地址:https://www.cnblogs.com/shyroke/p/7297816.html