Maven实战(五)-- 依赖管理

来源:互联网 发布:青岛淘宝代理 编辑:程序博客网 时间:2024/05/21 17:45

1.依赖配置

<dependencies>    <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>4.12</version>            <classifier></classifier>            <scope>test</scope>            <type></type>            <optional></optional>            <exclusions>                <exclusion>                    <artifactId></artifactId>                    <groupId></groupId>                </exclusion>            </exclusions>    </dependency></dependencies>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • groupId,artifactId:在上一章,坐标中已经说明,用于maven对于构件的定位
  • version:版本
  • classifier:用来定义构建输出的一些附属构建
  • scope:依赖范围,有以下值 
    1. compile,默认值,适用于所有阶段,会随着项目一起发布。
    2. provided,编译和测试的有用,在运行时无效,如servlet-api,在编译和测试的时候需要依赖,但是运行时,容器已经提供,所以不需要再次引入
    3. runtime,只在运行时使用,如JDBC驱动,适用运行和测试阶段。
    4. test,只在测试时使用,用于编译和运行测试代码。不会随项目发布。
    5. system,类似provided,需要再使用systemPath元素显示制定依赖文件路径,如下。(由于绑定本地文件,在其他计算机不一定存在,所以尽量不要使用)
<scope>system</scope><systemPath>${java.home}/lib/rt.jar</systemPath>
  • 1
  • 2
  • 1
  • 2
  • type:依赖类型,对应项目坐标定义的packaging,默认不用声明,为jar
  • optional:标记依赖是否可选,有true和false。如果A依赖于B,但是B只是A在测试时使用,这个时候X依赖于A,那么A就不需要B,那么在A的pom中配置optional为true的话,则在x编译的时候会忽略B的依赖。
  • exclusions:用来排除传递性依赖。比如,我们的项目A中引入了第三方构件B,但是B中又引入了C和D,但是D对于我们的项目有冲突那么我们可以配置如下,将D这个依赖忽略
<exclusion>    <artifactId>D</artifactId>    <groupId>D</groupId></exclusion>
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

2.依赖传递性

首先来看看依赖范围:

依赖范围对编译classpath有效对测试classpath有效对于运行时编译classpath有效例子compileYYYspring-coretest-Y-JUnitprovidedYY-servlet-apiruntime-YYJDBC驱动实现systemYY-本地的,Maven仓库以外的文件

如果我们在项目中配置一个依赖,但是这个依赖又有很多依赖,这样我们项目中就会存在许多不必要的jar,maven依赖传递性机制可以很好的解决这个问题。 
如果A依赖B,我们叫第一直接依赖,B依赖C我们叫第二直接依赖,它们的依赖范围会随传递性产生变化。

如下,左边为第一直接依赖,上面为第二直接依赖,他们之间传递性关系如下:

compiletestprovidedruntimecompilecompile--testtest--providedprovided-providedruntimeruntime--

由上面可以知道,如果A依赖于B,范围为test,B依赖于C,范围为compile,那么C是A范围为test的传递性依赖

3.依赖调解原则

例子一

A->B->C->X(1.0),A->D->X(2.0)这里对于X有两个版本的依赖,那么哪个会被Maven解析?都被解析是不对的,会造成依赖重复。 
maven依赖调解的第一原则:路径最近者优先,这里X(1.0)路径为3,X(2.0)为2,所以后者被解析使用。

例子二 
但是如下问题,第一原则无法解决: 
A->B->Y(1.0),A->C->Y(2.0),这里路径长度都是2,这里maven2.0.9开始又定义了第二原则:第一声明者优先

4.可选依赖

如果A->B

B中有如下依赖

<dependency>    <groupId>com.my.C</groupId>    <artifactId>cpt</artifactId>    <version>1.0.0</version>    <optional>true</optional></dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

通过上面配置,optional为true,那么A中就不会依赖这个cpt

5.排除依赖

snapshot–快照版和release–正式版

如果项目A依赖第三方依赖B,B又依赖SNAPSHOT版C那么C的不稳定会影响到A,这个时候就需要排除掉C。还有就是一个传递性依赖在中央仓库中对应的版本不存在,我们就需要排除依赖,然后再导入存在版本的依赖

<dependency>    <groupId>com.ys.b</groupId>    <artifactId>pro-b</artifactId>    <version>1.0.1</version><!--排除依赖-->    <exclusions>        <exclusion>            <groupId>com.ys.c</groupId>            <artifactId>pro-c</artifactId>        </exclusion>    </exclusions></dependency><!-- 引入正确依赖 --><dependency>    <groupId>com.ys.c</groupId>    <artifactId>pro-c</artifactId>    <version>1.0.0</version></dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

可以用下图表示: 
这里写图片描述

6.归并依赖

如果我们在pom中引入了多个依赖,比如spring相关的有core,beans,context等,这样如果我们需要修改版本,需要一个一个修改,十分麻烦 
这个时候就可以使用properties来定义

<properties>        <spring.version>4.1.3.RELEASE</spring.version></properties>
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

在指定版本的时候用如下形式

<version>${spring.version}</version>
  • 1
  • 1

7.查看依赖

mvn dependency:list以列表形式解析依赖
  • 1
  • 1

这里写图片描述

mvn dependency:tree以树的形式展示
  • 1
  • 1

这里写图片描述

8.顺序对依赖的影响(未经证实)

配置公司项目,有两个依赖,mybatis-3.4.1和公司的包core(含mybatis3.2.1)

原先配置顺序为

<mybatis><core>
  • 1
  • 2
  • 1
  • 2

这个时候,项目是正常的,但是我中途调整了下他们的顺序

<core><mybatis>
  • 1
  • 2
  • 1
  • 2

就报异常

java.lang.NoClassDefFoundError: org/apache/ibatis/reflection/ReflectorFactory
  • 1
  • 1

ReflectorFactory在3.2中是不存在的,在3.4中是有的,而且看项目中导入的是3.2的版本

总结:依赖应该是以先定义的优先

原创粉丝点击