讲讲 Maven 依赖

news/2025/1/12 4:03:13/

讲讲 Maven 依赖

  • 1.依赖配置
  • 2.依赖范围
  • 3.依赖冲突
  • 4.排除依赖

1.依赖配置

配置信息示例:

<project><dependencies><dependency><groupId></groupId><artifactId></artifactId><version></version><type>...</type><scope>...</scope><optional>...</optional><exclusions><exclusion><groupId>...</groupId><artifactId>...</artifactId></exclusion></exclusions></dependency></dependencies>
</project>

配置说明

  • dependencies: 一个 pom.xml 文件中只能存在一个这样的标签,是用来管理依赖的总标签。
  • dependency:包含在 dependencies 标签中,可以有多个,每一个表示项目的一个依赖。
  • groupId,artifactId,version(必要):依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven 根据坐标才能找到需要的依赖。
  • type(可选):依赖的类型,对应于项目坐标定义的 packaging。大部分情况下,该元素不必声明,其默认值是 jar。
  • scope(可选):依赖的范围,默认值是 compile。
  • optional(可选): 标记依赖是否可选
  • exclusions(可选):用来排除传递性依赖,例如 jar 包冲突

2.依赖范围

classpath 用于指定 .class 文件存放的位置,类加载器会从该路径中加载所需的 .class 文件到内存中。

Maven 在编译、执行测试、实际运行有着三套不同的 classpath:

  • 编译 classpath :编译主代码有效
  • 测试 classpath :编译、运行测试代码有效
  • 运行 classpath :项目运行时有效

Maven 的依赖范围如下:

  • compile:编译依赖范围(默认),使用此依赖范围对于编译、测试、运行三种都有效,即在编译、测试和运行的时候都要使用该依赖 Jar 包。
  • test:测试依赖范围,从字面意思就可以知道此依赖范围只能用于测试,而在编译和运行项目时无法使用此类依赖,典型的是 JUnit,它只用于编译测试代码和运行测试代码的时候才需要。
  • provided :此依赖范围,对于编译和测试有效,而对运行时无效。比如 servlet-api.jar 在 Tomcat 中已经提供了,我们只需要的是编译期提供而已。
  • runtime:运行时依赖范围,对于测试和运行有效,但是在编译主代码时无效,典型的就是 JDBC 驱动实现。
  • system:系统依赖范围,使用 system 范围的依赖时必须通过 systemPath 元素显示地指定依赖文件的路径,不依赖 Maven 仓库解析,所以可能会造成建构的不可移植。

3.依赖冲突

1、对于 Maven 而言,同一个 groupId 同一个 artifactId 下,只能使用一个 version。

<dependency><groupId>in.hocg.boot</groupId><artifactId>mybatis-plus-spring-boot-starter</artifactId><version>1.0.48</version>
</dependency>
<!-- 只会使用 1.0.49 这个版本的依赖 -->
<dependency><groupId>in.hocg.boot</groupId><artifactId>mybatis-plus-spring-boot-starter</artifactId><version>1.0.49</version>
</dependency>

若相同类型但版本不同的依赖存在于同一个 pom 文件,只会引入后一个声明的依赖🦦

2、项目的两个依赖同时引入了某个依赖。

举个例子,项目存在下面这样的依赖关系:

依赖链路一:A -> B -> C -> X(1.0)
依赖链路二:A -> D -> X(2.0)

这两条依赖路径上有两个版本的 X,为了避免依赖重复,Maven 只会选择其中的一个进行解析。

哪个版本的 X 会被 Maven 解析使用呢?

Maven 在遇到这种问题的时候,会遵循 路径最短优先声明顺序优先 两大原则。解决这个问题的过程也被称为 Maven 依赖调解

路径最短优先🦈

依赖链路一:A -> B -> C -> X(1.0) // dist = 3
依赖链路二:A -> D -> X(2.0) // dist = 2

依赖链路二的路径最短,因此,X(2.0)会被解析使用。

不过,你也可以发现。路径最短优先原则并不是通用的,像下面这种路径长度相等的情况就不能单单通过其解决了:

依赖链路一:A -> B -> X(1.0) // dist = 3
依赖链路二:A -> D -> X(2.0) // dist = 2

因此,Maven 又定义了声明顺序优先原则。

声明顺序优先🐬

在依赖路径长度相等的前提下,在 pom.xml 中依赖声明的顺序决定了谁会被解析使用,顺序最前的那个依赖优胜。该例中,如果 B 的依赖声明在 D 之前,那么 X (1.0)就会被解析使用。

<!-- A pom.xml -->
<dependencies>...dependency B...dependency D
</dependencies>

4.排除依赖

单纯依赖 Maven 来进行依赖调解,在很多情况下是不适用的,需要我们手动排除依赖。

举个例子,当前项目存在下面这样的依赖关系:

依赖链路一:A -> B -> C -> X(1.5) // dist = 3
依赖链路二:A -> D -> X(1.0) // dist = 2

根据路径最短优先原则,X(1.0) 会被解析使用,也就是说实际用的是 1.0 版本的 X。

但是!!!这会一些问题:如果 D 依赖用到了 1.5 版本的 X 中才有的一个类,运行项目就会报NoClassDefFoundError错误。如果 D 依赖用到了 1.5 版本的 X 中才有的一个方法,运行项目就会报NoSuchMethodError错误。

如何解决呢? 我们可以通过exclusive标签手动将 X(1.0) 给排除。

<dependency>......<exclusions><exclusion><artifactId>x</artifactId><groupId>org.apache.x</groupId></exclusion></exclusions>
</dependency>

http://www.ppmy.cn/news/20704.html

相关文章

刚来的00后太卷了,上班还没2年,跳到我们公司起薪25k....

都说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。 这不&#xff0c;前段时间我们公司来了个00后&#xff0c;工作都没两年&#xff0c;跳槽到我们公司起薪18K&#xff0c;都快接近我了。后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了…

深度学习三件套安装依赖指南

安装依赖指南 标准的深度学习三件套包括pytorch, cuda, cudnn。根据经验&#xff0c;一般安装顺序如下&#xff1a; 用conda安装cudaconda install cudatoolkit11.7&#xff0c;使用清华源&#xff08;到官网确认安装了符合pytorch要求的cuda版本&#xff09;用pip安装pytorc…

C++——map|set2

目录 map::operator[] [ ]的实现 multimap 习题 前K个高频单词 两个数组的交集 底层结构 pair有俩个成员一个是first,一个是second 由于pair有俩个模板参数&#xff0c;第一个是first&#xff0c;一个是second map的insert参数类型是valud_type,value_type就是pair …

.mp4 文件转化成 .bag 文件并在 rviz 中显示

文章目录一、Python实现.mp4和.bag相互转化1、.mp4转.bag验证是否转换成功&#xff1a;使用 rosplay2、.bag转.mp4二、rviz 读取 *.bag 数据包并显示1、查看bag数据包的基本信息2、rviz 显示信息一、Python实现.mp4和.bag相互转化 1、.mp4转.bag # -*- coding: utf-8 -*- ##i…

Qt扫盲-QDateTime理论总结

QDateTime理论使用总结一、概述二、使用1. 构造初始化对象2. 获取属性3. 字符串和QDateTime互转4. 时间比较3. 注意三、使用时区四、夏令时(DST)一、概述 QDateTime对象编码日历日期和时钟时间(“datetime”)。它结合了QDate和QTime类的特性。它可以从系统时钟读取当前的datet…

Matlab pdetool

云溪岩绵迎彩霞,博主精神压力大呀,没人说说知心话啊,SCU物理要命啦........基本物理方程静电磁场交流电磁场热传导Options->ApplicationGeneric Scalar泛型标量Generic System通用系统Structural Mechanics,Plane Stress结构力学 - 平面应力Structural Mechanics,Plane Stra…

参数检验与非参数检验

综述 假设检验 参数检验 T检验 T检验是通过比较不同数据的均值&#xff0c;研究两组数据之间是否存在显著差异。 单总体检验&#xff1a;单总体t检验是检验一个样本平均数与一个已知的总体平均数的差异是否显著。当总体分布是正态分布&#xff0c;如总体标准差未知且样本容量小…

Docker安装使用系列七之内部程序可视化

基于Docker进行项目开发时&#xff0c;当需要在docker容器里运行一些qt图形界面的软件以及ros等&#xff0c;或者要调用摄像头&#xff0c;输出图像等等一些需求&#xff0c;这个时候需要解决这个Docker “可视化”的问题&#xff0c;注意这里不是网上一搜一大把的那种可视化容…