Maven 依赖传递和冲突、继承和聚合

一、依赖传递和冲突

1.1 Maven 依赖传递特性

1.1.1 概念

        假如有三个 Maven 项目 ABC,其中项目依赖 B,项目 依赖 C。那么我们可以说 A 依赖 C。也就是说,依赖的关系为:A—>B—>C, 那么我们执行项目 A 时,会自动把 BC 都下载导入到 A 项目的 jar 包文件夹中,这就是依赖的传递性。

1.1.2 作用

        1、简化依赖导入过程

        2、确保依赖版本正确

1.1.3 传递的原则

        在 A 依赖 BB 依赖 C 的前提下,C 是否能够传递到 A,取决于 B 依赖 C 时使用的依赖范围以及配置。

        1、B 依赖 C 时使用 compile 范围:可以传递

        2、B 依赖 C 时使用 test provided 范围:不能传递,所以需要这样的 jar 包时,就必须在需要的地方明确配置依赖才可以。

        3、B 依赖 C 时,若配置了以下标签,则不能传递

<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.15</version><!-- 是否中断依赖--><optional>true</optional>
</dependency>

1.1.4 依赖传递中止的情况

        1、compile 范围进行依赖传递

        2、使用 optional 配置终止传递

        3、依赖冲突(传递的依赖已经存在)

1.1.5 案例

        比如说,我们在使用 jackson 时,需要导入下面的三个依赖。

<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.14.2</version>
</dependency>
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.14.2</version>
</dependency>
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.14.2</version>
</dependency>

        但是根据依赖的传递关系,在 databind 里面是依赖其他两个依赖的,也就是说只需要导入一个 databind 即可,如下图:

1.2 Maven 依赖冲突特性

1.2.1 依赖冲突简介

        当直接引用或者间接引用出现了相同的 jar 包,此时项目就会出现相同的重复 jar 包,这就算作冲突。如下图:

        maven 拥有自动解决依赖冲突问题能力,会按照自己的原则,进行重复依赖选择。同时也提供了手动解决的冲突的方式。

1.2.2 自动选择

1.2.2.1 短路优先(第一原则)

        下面的两条路径第二条路径短(依赖的层级小),所以最终 A 会依赖 X(version 0.0.2)

        1、A —> B —> C —> D —> E —> X(version 0.0.1)

        2、A —> F —> X(version 0.0.2)

1.2.2.2 先声明优先(第二原则)

        依赖路径长度相同情况下,则谁先声明谁优先,即在项目 A pom 中,如果先声明的是 E ,那么就依赖 X(version 0.0.1),如果先声明的是 F ,那么就依赖 X(version 0.0.2)版本。

        1、A—>E—>X(version 0.0.1)

        2、A—>F—>X(version 0.0.2)

1.2.3 手动排除

        可以在 dependency 标签里面添加 exclusion 标签来排除依赖,如下所示:

<dependency><groupId>com.maven</groupId><artifactId>pro01-maven-java</artifactId><version>1.0-SNAPSHOT</version><scope>compile</scope><!-- 使用 excludes 标签配置依赖的排除  --><exclusions><!-- 在 exclude 标签中配置一个具体的排除 --><exclusion><!-- 指定要排除的依赖的坐标(不需要写version) --><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions>
</dependency>

二、继承和聚合

2.1  Maven 工程继承关系

2.1.1 继承概念

        Maven 继承是指在 Maven 的项目中,让一个项目从另一个项目中继承配置信息的机制。继承可以让我们在多个项目中共享同一配置信息,简化项目的管理和维护工作。

2.1.2 继承作用

        在父工程中统一管理项目中的依赖信息。

2.1.3 背景

        1、对一个比较大型的项目进行了模块拆分。

        2、一个 project 下面,创建了很多个 module

        3、每一个 module 都需要配置自己的依赖信息。

2.1.4 需求

        1、在每一个 module 中各自维护各自的依赖信息很容易发生出入,不易统一管理。

        2、使用同一个框架内的不同 jar 包,它们应该是同一个版本,所以整个项目中使用的框架版本需要统一。

        3、使用框架时所需要的 jar 包组合(或者说依赖信息组合)需要经过长期摸索和反复调试,最终确定一个可用组合。这个耗费很大精力总结出来的方案不应该在新的项目中重新摸索。

        4、通过在父工程中为整个项目维护依赖信息的组合既保证了整个项目使用规范、准确的 jar 包;又能够将以往的经验沉淀下来,节约时间和精力。

2.1.5 继承语法

        父工程里面的 pom.xml 内容如下:

<groupId>com.maven</groupId>
<artifactId>maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 当前工程作为父工程,它要去管理子工程,所以打包方式必须是 pom -->
<packaging>pom</packaging>

        子工程里面的 pom.xml 内容如下:

<!-- 使用parent标签指定当前工程的父工程 -->
<parent><!-- 父工程的坐标 --><groupId>com.maven</groupId><artifactId>maven-parent</artifactId><version>1.0-SNAPSHOT</version>
</parent><!-- 子工程的坐标 -->
<!-- 如果子工程坐标中的groupId和version与父工程一致,那么可以省略 -->
<artifactId>maven-module</artifactId>

2.1.6 案例

        首先创建一个 maven-parent 模块作为父工程,如下:

          这个 src 目录没有什么用,因为这个 module 只是作为父工程,不会在里面编写代码,所以可以给他删除掉,最终的效果如下图:

        maven-parent pom.xml 的内容如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.maven</groupId><artifactId>maven-parent</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties></project>

        在  maven-parent 模块下右键,创建一个子工程 maven-son,如下图:

        项目的整体架构如下图所示: 

        maven-sonpom.xml 内容如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><!-- 使用 parent 标签指定当前工程的父工程 --><parent><groupId>com.maven</groupId><artifactId>maven-parent</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>maven-son</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties></project>

        此时,一个 maven 的父子工程就创建成功了。

2.1.7 dependencies 标签

        如果想要子工程完全继承父工程的 maven 依赖,那么只需要在父工程里面使用 dependencies 标签添加依赖即可,如下图,且继承依赖的关系不受 <scope> 标签里面的属性影响。

        子工程不用在 pom.xml 里面配置任何的依赖即可享受父工程的所有依赖。

2.1.8 dependencyManagement 标签

        一般父工程的依赖都比较多,如果子工程不需要依赖全部,只需要依赖其中的几个,那么就需要使用 dependencyManagement 标签了。

        首先在 maven-parent 项目里面使用 dependencyManagement 标签来管理依赖,如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.maven</groupId><artifactId>maven-parent</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><modules><module>maven-son</module></modules><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencyManagement><dependencies><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.14.2</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.20</version><scope>provided</scope></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.9.2</version><scope>test</scope></dependency></dependencies></dependencyManagement>
</project>

        一旦父工程使用 dependencyManagement 标签,那么 maven-son 项目的依赖就变成 0 了,如下图 

        此时,就需要在 maven-son 项目里面指定自己想要的依赖,如下图,版本号不用写,只需要写前面两个坐标即可,配置 maven-son 的依赖,如下图:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.maven</groupId><artifactId>maven-parent</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>maven-son</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency></dependencies>
</project>

        可以看到,出现了自己想要的依赖,如下图 

2.2 Maven 工程聚合关系

2.2.1 聚合概念

        Maven 聚合是指将多个项目组织到一个父级项目中,以便一起构建和管理的机制。聚合可以帮助我们更好地管理一组相关的子项目,同时简化它们的构建和部署过程。

2.2.2 聚合作用

        1、管理多个子项目,通过聚合,可以将多个子项目组织在一起,方便管理和维护。

        2、构建和发布一组相关的项目,通过聚合,可以在一个命令中构建和发布多个相关的项目,简化了部署和维护工作。

        3、优化构建顺序,通过聚合,可以对多个项目进行顺序控制,避免出现构建依赖混乱导致构建失败的情况。

        4、统一管理依赖项,通过聚合,可以在父项目中管理公共依赖项和插件,避免重复定义。

2.2.3 聚合语法

        在父项目中包含的子项目列表。如下,主要是 modules 标签。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.maven</groupId><artifactId>maven-parent</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><modules><!-- 这个是工程路径,不是工程名称--><module>maven-son</module></modules><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties></project>

2.2.4 聚合演示

        我们构建一个 maven-parent 项目,看看他是否可以自动构建他的子项目 maven-son,如下图:

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PDF有编辑密码怎么办

目录 注意&#xff1a; windows方法&#xff1a; 1 python 下载 2 打开命令行 3 安装 pikepdf 4 编写python脚本 5 使用py脚本 6解密完成 Linux方法&#xff1a; 注意&#xff1a; 此方法可以用于破解PDF的编辑密码&#xff0c;而不是PDF的打开密码 当遇到类似如下问…

MySQL语句 | 在MySQL中解析JSON或将表中字段值合并为JSON

MySQL提供了一系列的JSON函数来处理JSON数据&#xff0c;包括从JSON字符串中提取值和将表中字段值合并为JSON等。 在MySQL中解析JSON 可使用JSON_EXTRACT函数提取JSON字符串中指定字段的值&#xff0c;使用JSON_UNQUOTE函数去除提取的字符串值周围的引号&#xff0c;以得到原…

openssl3.2 - 官方demo学习 - signature - rsa_pss_direct.c

文章目录 openssl3.2 - 官方demo学习 - signature - rsa_pss_direct.c概述笔记END openssl3.2 - 官方demo学习 - signature - rsa_pss_direct.c 概述 用RSA私钥签名 d2i_PrivateKey_ex()可以从内存载入私钥数据, 得到私钥EVP_PKEY* 从私钥产生ctx, 对ctx进行签名初始化, 设置…

mavavi显示 3d姿态

目录 mayavi安装&#xff1a; mavavi显示 3d姿态 mayavi安装&#xff1a; 第1步 从这里下载两个whl文件&#xff0c; https://www.lfd.uci.edu/~gohlke/pythonlibs/ * mayavi&#xff1a;*xxx.whl * vtk: VTK‑9.1.0‑cp310‑cp310‑win_amd64.whl 第2步 pip install py…

linux-挂载Samba共享

linux-挂载Samba共享 1、linux服务器启动Samba共享服务 2、客户端电脑安装cifs-utils dnf install cifs-utils # 或 yum install cifs-utils3、挂载共享目录 # 创建挂目录 mkdir /share # 使用mount命令挂在共享目录&#xff0c;-t协议类型 -o用户名密码 共享目录访问地址 挂…

无监督学习 - 均值聚类(K-Means Clustering)

什么是机器学习 K-Means聚类是一种无监督学习算法&#xff0c;用于将数据集分成K个不同的组&#xff08;簇&#xff09;&#xff0c;每个组内的数据点与组内其他点的相似度较高&#xff0c;而与其他组内的点相似度较低。这是通过迭代地调整簇中心和将数据点分配到最近的簇来实…

热压机PLC数据采集远程监控物联网解决方案

热压机PLC数据采集远程监控物联网解决方案 随着工业4.0时代的到来&#xff0c;智能制造已经成为制造业发展的重要方向。在热压机领域&#xff0c;PLC数据采集远程监控物联网解决方案为提高生产效率、降低维护成本、优化生产工艺提供了有效的手段。 一、热压机PLC数据采集远程…

canvas绘制美队盾牌

查看专栏目录 canvas示例教程100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

【Rust学习】安装Rust环境

本笔记为了记录学习Rust过程&#xff0c;内容如有错误请大佬指教 使用IDE&#xff1a;vs code 参考教程&#xff1a;菜鸟教程链接: 菜鸟教程链接: Rust学习 Rust入门安装Rust编译环境Rust 编译工具 构建Rust 工程目录 Rust入门 安装Rust编译环境 因为我已经安装过VSCode了&am…

解决若依Vue3前后端分离---路由切换时显示白屏

解决若依Vue3前后端分离---路由切换时显示白屏 1.问题重述 解决基于Vue3若依前后端分离项目中出现的路由正常切换但是就是不显示数据的问题&#xff0c;也就是不发起网络请求的问题。 找到如下位置中AppMain.vue文件 将除了css中的代码进行替换成如下的代码。 <template&g…

kylin集群负载均衡(kylin3,hbaseRIF问题)

hbase历险记 目录 hbase历险记 寻找问题 分析原因 解决方案 方案1&#xff08;资源问题、失败&#xff09; 方案2&#xff08;成功&#xff09; 寻找问题 不知道你是不是有这样的疑惑。我kylin是个单机&#xff0c;我使用的hbase是个集群&#xff0c;但内存全在某一台机…

vue2使用qiankun微前端(跟着步骤走可实现)

需求&#xff1a;做一个vue2的微前端&#xff0c;以vue2为主应用&#xff0c;其他技术栈为子应用&#xff0c;比如vue3&#xff0c;本文章只是做vue2一套的微前端应用实现&#xff0c;之后解决的一些问题。vue3子应用可以看我另一篇vue3vitets实现qiankun微前端子应用-CSDN博客…

Spring Boot多环境配置

Spring Boot的针对不同的环境创建不同的配置文件&#xff0c; 语法结构&#xff1a;application-{profile}.properties profile:代表的就是一套环境 需求 application-dev.yml 开发环境 端口8090 application-test.yml 测试环境 端口8091 application-prod.yml 生产环境 端口80…

前端八股文(性能优化篇)

目录 1.CDN的概念 2.CDN的作用 3.CDN的原理 4.CDN的使用场景 5.懒加载的概念 6.懒加载的特点 7.懒加载的实现原理 8.懒加载与预加载的区别 9.回流与重绘的概念及触发条件 &#xff08;1&#xff09;回流 &#xff08;2&#xff09;重绘 10. 如何避免回流与重绘&#…

如何在ubuntu18.04安装python3.8.6

目录 一.前言 二.教程 2.1环境配置 2.2下载安装包 2.3编译安装 2.4验证安装

Ubuntu服务器上使用tmux

&#xff08;1&#xff09;服务器上安装 $ sudo apt-get install tmux &#xff08;2&#xff09;新建会话 &#xff08;之后可以正常运行程序&#xff09; $ tmux new -s session_name &#xff08;3&#xff09;查看当前所有的tmux会话 $ tmux ls &#xff08;4&#xff09;退…

Deep MultimodalLearningA survey on recent advances and trends

深度多模态学习&#xff1a;对近期进展和趋势的综述 深度学习的成功已经成为解决越来越复杂的机器学习问题的催化剂&#xff0c;这些问题通常涉及多个数据模态。我们回顾了深度多模态学习的最新进展&#xff0c;并突出了该活跃研究领域的现状&#xff0c;以及存在的差距和挑战…

【动态规划】【C++算法】639 解码方法 II

作者推荐 【矩阵快速幂】封装类及测试用例及样例 涉及知识点 动态规划 字符串 滚动向量 LeetCode 639. 解码方法 II 一条包含字母 A-Z 的消息通过以下的方式进行了 编码 &#xff1a; ‘A’ -> “1” ‘B’ -> “2” … ‘Z’ -> “26” 要 解码 一条已编码的消息…

【已解决】c语言const/指针学习笔记

本博文源于笔者正在复习const在左与在右&#xff0c;指针优先级、a,&a,*a的区别。 1、const在左与在右 int const *p const int *p int * const p int const * const p const int * const p* 在const右边&#xff0c;指向的数据不可以改变&#xff0c;可以改变地址 * 在c…

不同打包工具下的环境变量配置方式对比

本文作者为 360 奇舞团前端开发工程师 天明 前言 在现代的JavaScript应用程序开发中&#xff0c;环境变量的配置是至关重要的。不同的应用场景和部署环境可能需要不同的配置&#xff0c;例如开发、测试和生产环境。最常见的需求是根据不同的环境&#xff0c;配置如是否开启sour…