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.hqwc.cn/news/418665.html

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

相关文章

ubuntu设置每天定时关机

ubuntu设置每天定时关机 终端输入命令&#xff1a; sudo crontab -e输入密码&#xff0c;回车。 我这里使用nano作为编辑器&#xff0c;你可以选择vim。 在末尾输入以下命令&#xff1a; 59 23 * * * sudo -u root shutdown now设置&#xff1a;每天23:59分&#xff0c;电脑…

基于springboot+vue养老院管理系统

摘要 这是一个基于Spring Boot 和 Vue.js 的养老院管理系统的项目。该系统旨在提供一套全面的解决方案&#xff0c;以简化养老院的日常管理任务&#xff0c;包括居民信息管理、员工调度、医疗服务追踪、财务管理等。通过结合后端的Spring Boot框架和前端的Vue.js框架&#xff0…

Oracle 经典练习题 50 题

文章目录 一 CreateTable二 练习题1 查询"01"课程比"02"课程成绩高的学生的信息及课程分数2 查询"01"课程比"02"课程成绩低的学生的信息及课程分数3 查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩4 查询平均成绩小于…

VS Code + Python + Selenium 自动化测试基础-01

VS Code Python Selenium 自动化测试基础-01 让我们来讲一个故事为什么要写自动化开发前的准备工作牛刀小试开常用的web DriverAPI-定位元素id定位&#xff1a;find_element_by_id()name 定位&#xff1a;find_element_by_name()class 定位&#xff1a;find_element_by_class…

redis远程连接不上解决办法

问题描述&#xff1a; redis远程服务端运行在192.168.3.90计算机上&#xff0c;客户端计算机&#xff08;ip:192.168.3.110&#xff09;通过redsi-cli.exe客户端工具连接时&#xff0c;没有反应&#xff0c;连接不上。 如图所示&#xff1a; 解决步骤&#xff1a; 步骤一&…

Civil 3D安装教程,免费使用,带安装包和工具,一分钟轻松搞的安装

前言 Civil 3D是一款面向基础设施行业的建筑信息模型&#xff08;BIM&#xff09;解决方案。它为基础设施行业的各类技术人员提供了强大的设计、分析以及文档编制功能&#xff0c;广泛适用于勘察测绘、岩土工程、交通运输、水利水电、市政给排水、城市规划和总图设计等众多领域…

【高等数学之极限】

一、引言 我们先思考一下&#xff0c;上面三个表达式&#xff0c;是否可以将极限值直接代入求值&#xff0c;我们在计算之前需要先分析一下&#xff0c;如果将极限值代入&#xff0c;那么表达式将会变成什么形式? 经过上面的分析&#xff0c;我们发现第一个式子可以直接带入&a…

Python 中多线程与多处理之间的区别

一、说明 在本文中&#xff0c;我们将学习 Python 中多线程和多处理的内容、原因和方式。在我们深入研究代码之前&#xff0c;让我们了解这些术语的含义。 二、基本术语和概念 程序是一个可执行文件&#xff0c;它由一组执行某些任务的指令组成&#xff0c;通常存储在计算机的…

BGP Origin 属性控制选路试验

一、拓朴图&#xff1a; 二、配置步骤&#xff1a; 1、配置 IP 2、配置 IGP&#xff0c;我们这里用了静态&#xff0c;互相宣告了对端接口和 Loopback 0 3、配置 BGP 4、在 R1 上通过 BGP 宣告 1.1.1.1&#xff0c;查看 R2 的路由&#xff0c;发现两条 1.1.1.1 的路由&#x…

解决小程序字体在最左上角问题

问题如下 原因&#xff1a; 出现这种现象的原因是项目默认开启了Skyline渲染模式&#xff0c;因为Skyline渲染模式不支持原生导航栏&#xff0c;所以在json文件中设置的导航栏失效&#xff0c;文字就会向上移动&#xff0c;如果想要使用原生的导航栏&#xff0c;可以将app.jso…

App 测试工具大全,收藏这篇就够了

随着移动互联网的高速发展&#xff0c;App应用非常火&#xff0c;测试工程师也会接触到各种app应用。除了人工测试之外&#xff0c;也可以通过一些测试工具来提高我们的测试效率&#xff0c;以下对于我用过或听过的app测试工具做了一个统一整理&#xff0c;欢迎补充。 一、APP自…

SpringMVC简介和SpringMVC的HelloWorld

一、SpringMVC简介 1、什么是MVC MVC是一种软件架构的思想&#xff0c;将软件按照模型、视图、控制器来划分 M&#xff1a;Model&#xff0c;模型层&#xff0c;指工程中的JavaBean&#xff0c;作用是处理数据 JavaBean分为两类&#xff1a; 一类称为实体类Bean&#xff1a…