【Maven篇】解锁 Maven 的智慧:依赖冲突纷争下的版本调停者

在这里插入图片描述

缘起

软件开发世界是一个充满无限可能的领域,但同时也伴随着诸多挑战。其中之一,就是依赖冲突的问题。在这篇文章中,我们将揭开 Maven 这位“版本调停者”的神秘面纱,深入探讨如何在版本纠纷的盛宴中解决依赖问题。

Maven:版本的裁判

Maven,就像是项目的裁判,负责处理各种依赖版本之间的纠纷。它的策略既有技巧,又充满智慧,确保项目能够顺利运行,而不被版本的纷争所困扰。

依赖声明:引子

在 Maven 的舞台上,一切从依赖声明开始。通过在项目的 pom.xml 文件中声明依赖,我们告诉 Maven 项目需要哪些库以及它们的版本。下面是一个简单的例子:

<!-- pom.xml -->

<dependencies>
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>library-a</artifactId>
        <version>1.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>library-b</artifactId>
        <version>2.0.0</version>
    </dependency>
</dependencies>

在这个例子中,我们引入了两个库:library-a 版本为 1.0.0library-b 版本为 2.0.0

依赖范围:规则的指引

Maven 还引入了依赖范围的概念,这就是规则的指引。通过合理设置依赖范围,我们可以更好地控制每个库的使用场景,避免不必要的冲突。

  • compile:默认范围,对于所有阶段都有效,包括编译、测试、运行等。
  • provided:在编译和测试阶段有效,但在运行时由 JDK 或容器提供。
  • runtime:在运行和测试阶段有效,但在编译时不需要。
  • test:仅在测试阶段有效,不会被传递到运行阶段。

理解这些范围,就像是学习项目中不同角色的职责一样,每个库都有它在项目中的“工作范围”。

Maven 的解决之道

在项目中,不同模块可能对同一个库有不同的版本需求。这就是依赖冲突的问题。而 Maven 通过一系列规则和算法来解决这个问题。接下来让我们逐一深入了解这些策略。

1. 最短路径优先原则

这个原则基于最短路径的概念。Maven 在构建项目的依赖树时,会选择离项目最近的依赖。最短路径即最直接的路径,这样可以确保使用的是最近的版本。例如:

<!-- Module A pom.xml -->

<dependency>
    <groupId>org.example</groupId>
    <artifactId>library-x</artifactId>
    <version>1.0.0</version>
</dependency>
<!-- Module B pom.xml -->

<dependency>
    <groupId>org.example</groupId>
    <artifactId>library-x</artifactId>
    <version>2.0.0</version>
</dependency>

如果 Module A 和 Module B 同时引入了 library-x,Maven 会选择使用 Module B 中声明的版本(2.0.0),因为它离项目更近。

2. 最先声明优先原则

这个原则强调的是先声明的依赖更优先。当同一个库被多个模块引入时,Maven 会选择最先声明该库的模块中所声明的版本。例如:

<!-- Module A pom.xml -->

<dependency>
    <groupId>org.example</groupId>
    <artifactId>library-x</artifactId>
    <version>1.0.0</version>
</dependency>
<!-- Module B pom.xml -->

<dependency>
    <groupId>org.example</groupId>
    <artifactId>library-x</artifactId>
    <version>2.0.0</version>
</dependency>

如果 Module A 先声明了 library-x,那么 Maven 会选择使用 Module A 中声明的版本(1.0.0)。

3. 传递性依赖原则

这个原则涉及到依赖的传递性。如果一个库被多个依赖传递引入,Maven 会选择其中一个版本。这通常遵循前述的最短路径优先原则。例如:

<!-- Module A pom.xml -->

<dependency>
    <groupId>org.example</groupId>
    <artifactId>library-x</artifactId>
    <version>1.0.0</version>
</dependency>
<!-- Module B pom.xml -->

<dependency>
    <groupId>org.example</groupId>
    <artifactId>library-y</artifactId>
    <version>1.0.0</version>
</dependency>
<!-- Module C pom.xml -->

<dependency>
    <groupId>org.example</groupId>
    <artifactId>library-y</artifactId>
    <version>2.0.0</version>
</dependency>

如果 Module A 和 Module B 同时引入了 library-y,而 Module B 又引入了 library-x,Maven 会选择 library-y 的最短路径,通常是 Module B 中声明的版本(1.0.0)。

4. 排除传递性依赖

有时,我们希望在某个模块中排除某个传递性依赖,以解决冲突。这可以通过在 pom.xml 文件中使用 <exclusions> 元素来实现。例如:

<!-- Module A pom.xml -->

<dependency>
    <groupId>org.example</groupId>
    <artifactId>library-y</artifactId>
    <version>1.0.0</version>
    <exclusions>
        <exclusion>
            <groupId>org.example</groupId>
            <artifactId>library-x</artifactId>
        </exclusion>
    </exclusions>
</dependency>

通过这种方式,我们排除了对 library-x 的传递性依赖,确保 Module A 不受到 Module B 中对 library-x 的影响。

实战演练

让我们通过一个简单的实战演练,更加直观地感受 Maven 在解决依赖冲突中的智慧。考虑以下场景:

<!-- Module A pom.xml -->

<dependency>
    <groupId>org.example</groupId>
    <artifactId>library-x</artifactId>
    <version>1.0.0</version>
</dependency>
<!-- Module B pom.xml -->

<dependency>
    <groupId>org.example</groupId>
    <artifactId>library-x</artifactId>
    <version>2.0.0</version>
</dependency>
<!-- Module C pom.xml -->

<dependency>
    <groupId>org.example</groupId>
    <artifactId>library-y</artifactId>
    <version>1.0.0</version>
</dependency>
<!-- Module D pom.xml -->

<dependency>
    <groupId>org.example</groupId>
    <artifactId>library-y</artifactId>
    <version>2.0.0</version>
</dependency>

在这个例子中,Module A 和 Module B 引入了相同的库 library-x 不同版本,而 Module C 和 Module D 引入了相同的库 library-y 不同版本。接下来,我们构建项目,观察 Maven 是如何处理这些依赖冲突的。

mvn clean install

Maven 会根据前述的解决策略来决定最终使用的版本。在这个例子中,由于 Module B 离项目更近,Maven 可能会选择使用 Module B 中声明的 library-x 版本(2.0.0),而选择 Module D 中声明的 library-y 版本(2.0.0)。

结语

Maven,这位版本的裁判,在依赖冲突的领域展现了它的智慧和机智。通过最短路径优先、最先声明优先、传递性依赖原则以及排除传递性依赖等策略,Maven 在项目中解决了版本的纷争,确保了项目的稳定构建。

在你的软件开发旅程中,不要被依赖冲突的问题所困扰。理解 Maven 的解决策略,善用依赖范围,规避传递性依赖的陷阱,是每个开发者都应该掌握的技能。愿你的项目构建顺利,版本的纷争不再是无解的难题,而是一场被明智处理的盛宴。在版本的舞台上,愿你的项目始终闪耀着稳定而明亮的光芒!

作者信息

作者 : 繁依Fanyi
CSDN: https://techfanyi.blog.csdn.net
掘金:https://juejin.cn/user/4154386571867191

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/467569.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何选择合适的数据可视化工具?

如果是入门级的数据可视化工具&#xff0c;使用Excel插件就足够了&#xff01; Excel插件&#xff0c;tusimpleBI 是一款 Excel 图表插件&#xff0c;提供超过120项图表功能&#xff0c;帮助用户制作各种 Excel 所没有的高级图表&#xff0c;轻轻松松一键出图。 它能够制作10…

FPGA——DDR3的IP核

FPGA——DDR3的ip核 IP核配置基于MIG核代码基于AXI接口的DDR3 IP核配置 1 2 3 4 5 6 基于MIG核代码 控制MIG核的信号进行读写 module MIG_APP_Drive(input i_ui_clk ,input i_ui_rst ,input init_calib_…

Django templates 存放html目录

模板 一概述 模板由两部分组成&#xff0c;一部分是HTML代码&#xff0c;一部分是逻辑控制代码&#xff08;变量&#xff0c;标签&#xff0c;过滤器&#xff09; 作用&#xff1a;可以通过一些逻辑控制代码减少一些重复的操作更快速的生成HTML代码&#xff0c;并且实现简单的…

VSCode下使用github初步

由于各种需要&#xff0c;现在需要统一将一些代码提交搞github&#xff0c;于是有了在VSCode下使用github的需求。之前只是简单的使用git clone&#xff0c;代码提交这些用的是其他源代码工具&#xff0c;于是得学习实操下&#xff0c;并做一记录以备后用。 安装 VSCode安装 …

K8S POD 启动探针 startupProbe 的使用

当我们启动一个POD 时&#xff0c; 当k8s detect 里面的容器启动成功时&#xff0c; 就会认为这个POD 启动完成了&#xff0c; 通常就会在状态里表示 ready 1/1 … 例如 rootk8s-master:~# kubectl get pods NAME READY STATUS RESTARTS AGE bq-api-demo 1…

部署Zabbix Agents添加使能监测服务器_Windows平台_MSI/Archive模式

Windows平台 一、从MSI安装Windows代理,添加Windows Servers/PC 概述 可以从Windows MSI安装包(32位或64位) 安装Zabbix agent 32位包不能安装在64位Windows中 所有软件包都支持TLS,配置TLS可选 支持UI和命令行的安装。 1、下载Agent代理程序,使用Agent2升级版,官网链接如…

首次突破1000量子比特!德国TU Darmstadt发布全新量子处理架构

内容来源&#xff1a;量子前哨&#xff08;ID&#xff1a;Qforepost&#xff09; 编辑丨慕一 编译/排版丨沛贤 深度好文&#xff1a;1200字丨8分钟阅读 量子计算机能否进一步发展&#xff0c;关键在于量子系统如何更具有可扩展性。随着量子系统规模的扩大&#xff0c;其算力优…

【接口防重复提交】⭐️基于RedisLockRegistry 分布式锁管理器实现

目录 前言 思路 实现方式 实践 1.引入相关依赖 2.aop注解 3.切面类代码 4.由于启动时报错找不到对应的RedisLockRegistry bean&#xff0c;选择通过配置类手动注入&#xff0c;配置类代码如下 测试 章末 前言 项目中有个用户根据二维码绑定身份的接口&#xff0c;由于用户在…

Python aiohttp 使用指南:快速入门教程

aiohttp 就是 Python 中一款优秀的异步 Web 框架&#xff0c;它能够帮助我们构建高效的异步 Web 应用和异步 HTTP 客户端。在本文中&#xff0c;我们将深入探讨 aiohttp 是什么以及如何使用它&#xff0c;通过简单易懂的案例带领你理解异步编程&#xff0c;以及如何处理异步请求…

基于C语言的“贪吃蛇”游戏设计理念

3.功能描述&#xff1a;本游戏主要实现以下几种功能 图1.游戏功能模块 3.1. 贪吃蛇的控制功能&#xff1a;通过各种条件的判断&#xff0c;实现对游戏蛇的左移、右移、下移、上移、自由移动&#xff0c;贪吃蛇的加长功能。 3.2. 游戏显示更新功能&#xff1a;当贪吃蛇左右移动、…

信息系统项目管理师018:计算机网络(2信息技术发展—2.1信息技术及其发展—2.1.2计算机网络)

文章目录 2.1.2 计算机网络1.网络标准协议2.软件定义网络3.第五代移动通信技术 记忆要点总结 2.1.2 计算机网络 在计算机领域中&#xff0c;网络就是用物理链路将各个孤立的工作站或主机相连在一起&#xff0c;组成数据链路&#xff0c;从而达到资源共享和通信的目的。凡将地理…

DEYOv2: Rank Feature with Greedy Matchingfor End-to-End Object Detection

摘要 与前代类似&#xff0c; DEYOv2 采用渐进式推理方法 来加速模型训练并提高性能。该研究深入探讨了一对一匹配在优化器中的局限性&#xff0c;并提出了有效解决该问题的解决方案&#xff0c;如Rank 特征和贪婪匹配 。这种方法使DEYOv2的第三阶段能够最大限度地从第一和第二…

Day68:WEB攻防-Java安全原生反序列化SpringBoot攻防heapdump提取CVE

目录 Java安全-反序列化-原生序列化类函数 原生序列化类函数 SnakeYaml XMLDecoder ObjectInputStream.readObject 工具利用 ysoserial Yakit SerializedPayloadGenerator Java安全-SpringBoot框架-泄漏&CVE SpringBoot Actuator-黑白盒发现 人工识别 BurpSui…

华为配置WAPI-PSK安全策略实验

配置WAPI-PSK安全策略示例 组网图形 图1 配置WAPI-PSK安全策略组网图 配置流程组网需求配置思路配置注意事项操作步骤配置文件 配置流程 WLAN不同的特性和功能需要在不同类型的模板下进行配置和维护&#xff0c;这些模板统称为WLAN模板&#xff0c;如域管理模板、射频模板、VAP…

MATLAB的使用(二)

一&#xff0c;算法需求 算法五特性(1)有穷性。有穷性是指算法需在有穷步骤、有穷时间内结束。 (2)确定性。确定性是指每个步骤都有确切的意义&#xff0c;相同的输入有相同的输出。 (3)有效性。有效性是指可通过已实现的运算在有限次完成&#xff0c;或叫可行性。 (4)输入。…

信息学奥赛一本通之MAC端VSCode C++环境配置

前提 安装 Visual Studio CodeVSCode 中安装 C/C扩展确保 Clang 已经安装&#xff08;在终端中输入命令&#xff1a;clang --version 来确认是否安装&#xff09;未安装&#xff0c;在命令行执行xcode-select --install 命令&#xff0c;会自行安装&#xff0c;安装文件有点大…

超越传统的极限:解密B树与B+树的数据结构之美!

超越传统的极限&#xff1a;解密B树与B树的数据结构之美&#xff01; B树和B树是在计算机科学中常用的平衡查找树数据结构&#xff0c;它们在处理大规模数据和磁盘存储方面具有重要的优势。本文将深入介绍B树和B树的基本概念、特点以及它们在数据库和文件系统中的应用&#xff…

AR/MR产品设计(二):如何用一双手完成与虚拟对象的自然交互

AR/MR产品设计&#xff08;二&#xff09;&#xff1a;如何用一双手完成与虚拟对象的自然交互 - 知乎 手是我们与现实世界交互最重要的方式&#xff0c;同样在虚实混合的世界中是最重要的交互方式 在AR/MR/VR的交互中&#xff0c;手势交互会作为XR的重要交互动作&#xff0c;因…

强缓存和协商缓存

前言 计算机网络模型从底到上&#xff1a;物理层&#xff08;光纤、网线&#xff09;、链路层&#xff08;MAC地址&#xff09;、网络层&#xff08;IP协议&#xff09;、传输层&#xff08;TCP\UDP&#xff09;、应用层&#xff08;HTTP\FTP\DNS&#xff09;。HTTP协议是作用…

数据结构:栈「详解」

目录 一&#xff0c;栈的定义 二&#xff0c;栈的基本操作 1&#xff0c;顺序栈 1.1顺序栈的基本概念 1.2顺序栈的基本操作 2&#xff0c;链栈 2.1链栈的基本概念 2.2链栈的种类 2.3链栈的基本操作 三&#xff0c;栈的应用 1&#xff0c;函数递归调用 2&#xff0c;…