当前位置: 首页 > news >正文

聊聊Maven的依赖传递、依赖管理、依赖作用域

1. 依赖传递

在Maven中,依赖是会传递的,假如在业务项目中引入了spring-boot-starter-web依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.4</version>
</dependency>

那么业务项目不仅直接引入了spring-boot-starter-web依赖,还间接引入了spring-boot-starter-web的依赖项:

spring-boot-starterspring-boot-starter-jsonspring-boot-starter-tomcatspring-webspring-webmvc

Maven依赖关系如下图所示:

外部库如下图所示:

其中,业务项目对spring-boot-starter-web的依赖称为直接依赖,对spring-boot-starter-web的依赖项:

spring-boot-starterspring-boot-starter-jsonspring-boot-starter-tomcatspring-webspring-webmvc

的依赖称为间接依赖。

2. 依赖管理

dependencyManagement元素主要用来统一管理依赖项的版本号。

假如父项目的pom文件中声明了如下依赖:

<dependencyManagement><dependencies><dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.4</version></dependency></dependencies>
</dependencyManagement>    

那么子项目在添加该依赖时,可以不指定版本号:

<dependencies><dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId></dependency>
</dependencies>

Maven会自动找到父项目中声明的该依赖项的版本号,如下图所示:

这样的优点是可以统一在父项目中管理依赖项的版本号,如果需要升级版本,只需改动父项目一个地方即可,子项目不用改动。

说明:

1)dependencyManagement只是声明依赖项,并没引入依赖项,子项目仍需显式引入,不过可以不指定版本号

2)如果子项目不想使用继承的父项目中的版本号,在子项目中指定版本号即可

3. 依赖作用域

在Maven中,可以使用scope来指定当前依赖项的作用域,常见的值有:compile、provided、runtime、test、import等,如下所示:

<dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope>
</dependency>

3.1 compile

compile是默认的作用域,如果引入依赖时,没有明确指定作用域,则依赖作用域为compile。

作用域为compile的依赖,在编译、测试和运行时都是可用的,并且会参与项目的打包过程,该依赖会传递给依赖该模块的其他模块。

3.2 provided

作用域为provided的依赖,在编译和测试时是可用的,在运行时是不可用的,不会参与项目的打包过程,也不会传递给其他模块。

比如lombok依赖会在编译时生成相应的get、set等方法,在运行时就不需要这个依赖了,因此常常被指定为provided:

<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.16</version><scope>provided</scope>
</dependency>

因为被指定为provided,项目打包时是不包含lombok依赖项的,如下图所示:

如果将上面的代码<scope>provided</scope>删除的话,运行时是下图这样的:

以上验证需将项目打包方式改为war,打包后查看WEB-INF/lib目录

3.3 runtime

作用域为runtime的依赖,在测试和运行时是可用的,在编译时是不可用的,会参与项目的打包过程,也会传递给依赖该模块的

其他模块。

说明:

作用域为runtime的依赖中的类,在项目代码里不能直接用,用了无法通过编译(这里指的是在src/main/java下使用)。

以mysql-connector-java为例,假如引入依赖时是下面这样的:

<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version>
</dependency>

下面的示例代码是可以编译通过的:

如果将作用域修改为runtime,上面的示例代码无法通过编译:

<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version><scope>runtime</scope>
</dependency>

3.4 test

作用域为test的依赖,只在测试时可用(包括测试代码的编译、执行),不会参与项目的打包过程,也不会传递给其他模块。

常见的有junit、mockito等:

<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope>
</dependency>

因为被指定为test,项目打包时是不包含junit依赖项的,如下图所示:

如果将上面的代码<scope>test</scope>删除的话,运行时是下图这样的:

以上验证需将项目打包方式改为war,打包后查看WEB-INF/lib目录

说明:

作用域为test的依赖中的类或者注解只能在src/test/java下才可以使用,在src/main/java下无法使用,如junit包下的@Test注解和org.junit.Assert断言类。

3.5 import

每个项目,一般都会继承自一个父项目,在实际的工作中,这个父项目一般都是公司架构组提供的带有公司特色的一个基础项目,

当然也可以是spring boot官方的项目。

以spring boot官方的项目为例:

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.4</version>
</parent>

这个父项目中,会使用dependencyManagement标签对依赖项的版本统一管理,子项目中,可以按需引入父项目

dependencyManagement中定义的依赖,但可以不指定版本号(版本号会自动继承父项目中定义的版本号)。

但是存在以下2个问题:

  1. Maven是单继承的,一个项目只能有一个parent项目
  2. parent项目dependencyManagement中的依赖项会越来越多,不好管理

依赖作用域import的出现就是为了解决以上问题,它可以通过非继承的方式批量引入另一个依赖项中

dependencyManagement元素中定义的依赖项,如下所示:

<dependencyManagement><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-bom</artifactId><version>${spring-session-bom.version}</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>

说明:<scope>import</scope>只能用在dependencyManagement下type为pom的dependency中。

以上代码等价于添加了以下6个依赖项:

可以看出,使用<scope>import</scope>可以模块化的管理依赖项,提高复用性,pom文件也更加简洁。

3.6 区别

综上所述,各个依赖作用域的区别如下表所示:

scope取值编译时可用测试时可用运行时可用是否参与打包依赖传递
compile
provided×××
runtime×
test××××

4. 影响依赖传递的因素

4.1 依赖作用域(scope)

依赖作用域会影响依赖传递,从上表可以看出,如果scope为provided或者test,该依赖不会传递,只有scope为compile或者runtime,

该依赖才会传递。

4.2 可选依赖(optional)

通过dependency标签引入依赖时,可以通过<optional>指定该依赖是不是可选的,默认值为false:

<dependency><groupId>org.ehcache</groupId><artifactId>ehcache</artifactId><version>3.2.3</version><optional>true</optional>
</dependency>

如果<optional>值为true,那么这个依赖不会传递。

相关文章:

聊聊Maven的依赖传递、依赖管理、依赖作用域

1. 依赖传递 在Maven中&#xff0c;依赖是会传递的&#xff0c;假如在业务项目中引入了spring-boot-starter-web依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>…...

centos6/7 SOCKS5 堆溢出漏洞修复(RPM方式)curl 8.4 CVE-2023-38545 CVE-2023-38546

引用 https://darkdark.top/update-curl.html centos6 rpm 升级包下载&#xff1a;https://download.csdn.net/download/sinat_24092079/88425840 yum update libcurl-8.4.0-1.el6.1.x86_64.rpm curl-8.4.0-1.el6.1.x86_64.rpmcentos7 rpm 升级包下载&#xff1a;https://down…...

C#,数值计算——数据建模Proposal的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { public class Proposal { public Normaldev gau { get; set; } null; private double logstep { get; set; } public Proposal(int ranseed, double lstep) { this.gau…...

如何使用命令生成动态链接库.dll文件(保姆级教学)

如何使用命令生成动态链接库.dll文件 /*** file 如何使用命令生成动态链接库.dll文件* author jUicE_g2R(qq:3406291309)* * brief 教学演示* tool visual studio2022&#xff08;2019也适用&#xff09;* * copyright 2023.10* COPYR…...

Qt之模块介绍

Qt提供了很多功能模块&#xff0c;我们需要知道的是这些模块有些加入了标准库&#xff0c;有一些并没有加入到标准库。至于为什么没有加入到标准库通过chatgpt得到的答案如下&#xff1a; Qt 是一个强大的跨平台 C 框架&#xff0c;它包括了很多核心模块和功能&#xff0c;以支…...

Socks5代理和代理IP

在数字时代&#xff0c;网络工程师必须不断掌握新技术&#xff0c;以解决跨界电商、爬虫数据采集、出海业务扩展、网络安全保护以及游戏性能优化等各种技术挑战。本文将深入探讨Socks5代理和代理IP技术&#xff0c;它们在各个领域中的应用&#xff0c;如何为网络工程师提供了强…...

计算机指令、机器码

目录 背景 在软硬件接口中&#xff0c;CPU 帮我们做了什么事&#xff1f; 从编译到汇编&#xff0c;代码怎么变成机器码&#xff1f; 解析指令和机器码 总结延伸 背景 上大学的时候&#xff0c;我们系里教 C 语言程序设计的老师说&#xff0c;他们当年学写程序的时候&…...

MyLife - Docker安装Consul

Docker安装Consul 个人觉得像consul之类的基础设施在线上环境直接物理机安装使用可能会好些。但是在开发测试环境用docker容器还是比较方便的。这里学习下docker安装consul使用。 1. Consul 镜像库地址 Consul 镜像库地址&#xff1a;https://hub.docker.com/r/hashicorp/consu…...

Leetcode刷题笔记--Hot61-70

1--课程表&#xff08;207&#xff09; 主要思路&#xff1a; 用 in 记录每一门课程剩余的先修课程个数&#xff0c;当剩余先修课程个数为0时&#xff0c;将该课程加入到队列q中。 每修队列q中的课程&#xff0c;以该课程作为先修课程的所有课程&#xff0c;其剩余先修课程个数…...

python特别篇—github基本操作手册

一、开始使用 1.1 “Hello world” 1.1.1 github介绍 GitHub是一个基于Git版本控制系统的代码托管平台。它提供了一个在线的代码仓库&#xff0c;使开发者可以将自己的代码存储在云端&#xff0c;并与其他开发者进行协作。GitHub不仅仅是一个代码托管平台&#xff0c;还提供了…...

tiktok直播websocket序列化与反序列化

系列文章目录 websocket训练地址:https://www.qiulianmao.com,正在搭建中 基础-websocket逆向基础-http拦截基础-websocket拦截基础-base64编码与解码基础-protobuf序列化与反序列化视频号直播弹幕采集tiktok protobuf序列化与反序列化实战一:Http轮询更新中tikto...

微信picker弹出之后 , 背景变成灰色是怎么做的

微信小程序在弹出picker组件时&#xff0c;会将页面背景变为半透明的灰色&#xff0c;这是通过设置一个全屏的蒙层来实现的。 具体实现方法如下&#xff1a; 在WXML文件中&#xff0c;添加一个view元素作为蒙层&#xff0c;并设置其样式和属性&#xff1a; <view class&q…...

通用考勤后台管理系统

考勤后台系统&#xff0c;包括待办事项、人员管理、任务中心、任务详情、我的任务、客户管理、考勤功能几大功能&#xff0c;本后台系统以考勤打卡为主要功能&#xff0c;采用分屏布局的方式&#xff0c;简洁大方&#xff0c;使用方便...

LeetCode75——Day5

文章目录 一、题目二、题解 一、题目 345. Reverse Vowels of a String Given a string s, reverse only all the vowels in the string and return it. The vowels are ‘a’, ‘e’, ‘i’, ‘o’, and ‘u’, and they can appear in both lower and upper cases, more t…...

面向C++模块的开源 IFC SDK

早在 VS2019 v16.10 版本的时候&#xff0c;我们就官宣了对 C 模块(以及几乎所有其他 C 20 特性)的全面支持&#xff0c;包括 MSVC 编译器工具集&#xff0c;静态分析&#xff0c;智能感知和调试器等&#xff0c;而实现模块需要将 C 代码实现为一种内部的临时表示形式。 今天&…...

Docker开启远程访问+idea配置docker+dockerfile发布java项目

一、docker开启远程访问 1.编辑docker服务文件 vim /usr/lib/systemd/system/docker.servicedocker.service原文件如下&#xff1a; [Unit] DescriptionDocker Application Container Engine Documentationhttps://docs.docker.com Afternetwork-online.target docker.socke…...

基于nodejs+vue教学辅助管理系统

学生&#xff1b;首页、个人中心、本课程设计了线上教学辅助系统 ,学生可以此系统实现在线学习&#xff0c;作业提交管理、作业成绩管理。随着社会的快速发展&#xff0c;计算机的影响是全面且深入的。教师&#xff1a;首页、个人中心、课程信息管理、教学资料管理、作业信息管…...

Qt 子线程中无限递归的信号槽导致主线程槽失效的原因和解决办法

Qt 子线程中无限递归的信号槽导致主线程槽失效的原因和解决办法 问题描述 在一个 Qt6.5.3 的项目中&#xff0c;有一个 ImageProcessor 类负责在子线程中进行图像处理&#xff0c;并有一个 MainWindow 类在主线程中进行界面更新。虽然 ImageProcessor::processingDone 信号被…...

实施 DevSecOps 最佳实践

DevSecOps 是一个框架&#xff0c;它将开发 (Dev)、IT 运营 (Ops) 和安全 (Sec) 流程的实践融合到一个简化的流程中。使用这种方法&#xff0c;DevSecOps 团队能够确保将安全性集成到软件开发生命周期中&#xff0c;确保以“安全第一”的心态构建、部署和维护软件。在本教程中&…...

第56节——redux-toolkit中的createAction——了解

一、概念 createAction 是一个用于创建 Redux action creator 的函数&#xff0c;它可以让你更快地编写 Redux 相关的代码&#xff0c;并且更加易于阅读和维护。 二、简单示例 使用 createAction&#xff0c;你只需要传入一个字符串类型的 action type&#xff0c;然后它会返…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...