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

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>
  • 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>
  • 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>

2.依赖传递性

首先来看看依赖范围:

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

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

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

compiletestprovidedruntime
compilecompile--
testtest--
providedprovided-provided
runtimeruntime--

由上面可以知道,如果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>

通过上面配置,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>

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

6.归并依赖

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

<properties>
        <spring.version>4.1.3.RELEASE</spring.version>
</properties>

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

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

7.查看依赖

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

这里写图片描述

mvn dependency:tree以树的形式展示

这里写图片描述

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

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

原先配置顺序为

<mybatis>
<core>

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

<core>
<mybatis>

就报异常

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值