Maven 基础之依赖管理、范围、传递、冲突

祖传图片镇楼

文章目录

    • 关于依赖管理
      • 坐标和 mvnrepository 网站
      • pom.xml 中"引"包
    • 依赖范围
    • 依赖传递
    • 依赖冲突

关于依赖管理

坐标和 mvnrepository 网站

在 maven 中通过『坐标』概念来确定一个唯一确定的 jar 包。坐标的组成部分有:

元素说明
<groupId>定义当前 Maven 组织名称
<artifactId>定义实际项目名称
<version>定义当前项目的当前版本

[✔] 注意
任意两个不同包,它们的这三个属性必定至少有一项是不同的。即,三者的「组合」必须唯一。

那么如何确定一个 java 包的坐标?通过 https://mvnrepository.com 。

mvnrepository 是一个与中央仓库对应的查询系统。在这里你可以查询你所需要的 java 包的坐标。

你只需要复制粘贴你所查到的 java 包的坐标 <repository> 片段即可。

pom.xml 中"引"包

依赖管理」就是对项目中 jar 包的管理。可以在 pom.xml 文件中定义 jar 包的坐标,管理依赖。

整体结构(其它无关元素略)

project 
└── dependencies├── dependency├── dependency├── ...└── dependency

例如:

<dependencies><!--slf4j-api--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.25</version></dependency><!--slf4j-simple--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-simple</artifactId><version>1.7.25</version></dependency><dependency> ... </dependency>  <dependency> ... </dependency>  <dependency> ... </dependency>  </dependencies>

maven 项目会「引用」你本地仓库中的这些 java 包。理论上,你的本地仓库「应该有」这些包,如果没有,maven 会先从网络仓库中下载它们。如果网络仓库也没有,那么 maven 会报错。

这些 java 库在本地仓库的存放的路径规则是:

%homepath%/.m2/repository/<groupId>/<artifactId>/<version>

例如,上面的 slf4j-api 在本地仓库中的存放路径就是

C:\Users\hello world\.m2\repository\org\slf4j\slf4j-api\1.7.25

[✔] 注意
需要注意的是,maven 项目是在「引用」这些 java 库。在项目最终打包前,你的 maven 项目中并没有真正地「包含」这些 java 包,你会发现无论你「引用」多少 java 包,你的项目源码的文件夹大小实际上并没有增加(其中只有你的项目源码)。maven 就是通过这种方式来节约空间。

依赖范围

依赖范围
(Scope)
对 main classpath 有效对 test classpath 有效打入包中例子
compileYesYesYeslog4j
test-Yes-junit
prividedYesYes-servlet-api
runtime--Yesjdbc 驱动实现类

使用技巧:

  • compile<scope> 的默认值;
  • 错将 runtime 写成 compile ,对项目无影响;
  • 错将 test 写成 compile ,对项目无太大影响。不影响项目运行,仅仅是项目的 jar/war 包会变大;
  • 唯一需要仔细思考、分辨的是 provided 。如果 provided 被误写成了 compile 会导致项目发布运行时因为包冲突而无法运行,或出现 bug 。

[!attention] 注意
你需要留意、甚至记忆哪些包应该是 provided 的。

依赖传递

<dependencies><!--<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.25</version></dependency>--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-simple</artifactId><version>1.7.25</version></dependency><dependencies>

前面的这个依赖可以将 slf4j-api 去掉,也依然可行。原因在于,虽然我们没有声明引用、使用 lslf4j-api ,但是我们声明要引用、使用的 slf4j-simple 它要使用 slf4j-api ,因此,maven 仍然还是会把 slf4j-api 纳入我们的项目中。

[?] 我们如何知道 slf4j-simple 它会使用 slf4j-api ?

有两种方式:

  1. 在 mvnrepository.com 中查询 slf4j-simple 时,该网站上会列出它所依赖的其它的包(如果有的话)

  2. 开发工具会有图形化界面让你能看到包的依赖关系,你可以直观地看到,slf4j-simple 依赖于 slf4j-api 。这样你可以对你的 repositories 进行优化。

依赖冲突

依赖冲突指的是你的项目中「包含了同一个包的两个不同版本」。这种情况下通常会导致项目报错,或启动失败。

依赖冲突常见于两个场景:

  1. 同一个项目的两个开发人员不约而同想到使用同一个 java 库,而互相不知道。从而导致项目的 pom 中引入了同一个包的两个不同版本。

  2. 项目依赖于 A 和 B 两个库,看似没有问题,但是 B 库本身又依赖于 A 库(或者是,B 库依赖于 C 库,而 C 库依赖于 A 库)。从而导致项目中最终还是包含了 A 库的两个不同版本。

Maven 会自动解决依赖冲突问题,它基于 2 个原则来处理:

  1. 路径最近者优先

    项目 A 有如下的依赖关系:

    A -> B -> C -> X (1.0)

    A -> D -> X (2.0)

    maven 最终包含的会是 X 库的 2.0 版本。

  2. 路径相等,先声明者优先

    项目 A 有如下的依赖关系:

    A -> B -> Y(1.0)

    A -> C -> Y(2.0)

    若 pom 文件中 B 的依赖坐标先于 C 进行声明,则最终 Y 的版本为 1.0 。

在开发工具中,可以有图形化界面让你直观地看到依赖关系,其中会将依赖冲突展示出来。IDEA 图形化展示效果比 Eclipse 要更好。

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

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

相关文章

【C/C++】用return返回一个函数

2023年8月13日&#xff0c;周日早上 我的第一篇使用了动态图的博客 #include<iostream> #include<windows.h>int loop(){int i0;while(1){Sleep(1000);std::cout<<i<<std::endl;}return 1; }int main(){std::cout<<"程序开始"<<…

tp5中的事务处理

使用事务首先要数据库支持事务&#xff1b; 如下MySQL数据库user表开启事务支持&#xff0c;即设计表->引擎设置为InnoDB->保存 事务处理 1. 数据库的表引擎需要是 InnoDB 才可以使用&#xff0c;如果不是调整即可&#xff1b; 2. 事务处理&#xff0c;需要执行多个 SQ…

ORB-SLAM2学习笔记7之System主类和多线程

文章目录 0 引言1 整体框架1.1 整体流程 2 System主类2.1 成员函数2.2 成员变量 3 多线程3.1 ORB-SLAM2中的多线程3.2 加锁 0 引言 ORB-SLAM2是一种基于特征的视觉SLAM&#xff08;Simultaneous Localization and Mapping&#xff09;系统&#xff0c;它能够从单个、双目或RBG…

K8S系列二:实战入门

I. 配置kubectl 1.1 什么是kubectl&#xff1f; 官方文档中介绍kubectl是&#xff1a; Kubectl 是一个命令行接口&#xff0c;用于对 Kubernetes 集群运行命令。Kubectl的配置文件在$HOME/.kube目录。我们可以通过设置KUBECONFIG环境变量或设置命令参数–kubeconfig来指定其他…

优雅地处理RabbitMQ中的消息丢失

目录 一、异常处理 二、消息重试机制 三、错误日志记录 四、死信队列 五、监控与告警 优雅地处理RabbitMQ中的消息丢失对于构建可靠的消息系统至关重要。下面将介绍一些优雅处理消息丢失的方案&#xff0c;包括异常处理、重试机制、错误日志记录、死信队列和监控告警等。…

分布式系统的 38 个知识点

天天说分布式分布式&#xff0c;那么我们是否知道什么是分布式&#xff0c;分布式会遇到什么问题&#xff0c;有哪些理论支撑&#xff0c;有哪些经典的应对方案&#xff0c;业界是如何设计并保证分布式系统的高可用呢&#xff1f; 1. 架构设计 这一节将从一些经典的开源系统架…

wsl没有响应,wsl启动失败,docker启动失败

wsl的相关问题记录和解决 问题一&#xff1a;cmd命令窗口输入wsl后没有响应&#xff0c;会卡住&#xff0c;类似如图 排查&#xff1a; 输入 wsl -l -v看是否有东西输出&#xff1b;我的电脑没有东西输出&#xff0c;依旧是卡住;有内容请重启试试从开始菜单打开&#xff0c;点…

[保研/考研机试] KY80 进制转换 北京大学复试上机题 C++实现

题目链接&#xff1a; KY80 进制转换https://www.nowcoder.com/share/jump/437195121691735660774 描述 写出一个程序&#xff0c;接受一个十六进制的数值字符串&#xff0c;输出该数值的十进制字符串(注意可能存在的一个测试用例里的多组数据)。 输入描述&#xff1a; 输…

Maven 基础学习及使用

Maven1 Maven简介1.1 Maven模型1.2 仓库 2 Maven安装配置3 Maven基本使用3.1 Maven 常用命令3.2 Maven 生命周期 4 IDEA使用Maven4.1 IDEA配置Maven环境4.2 Maven 坐标详解4.3 IDEA 创建 Maven项目4.4 IDEA 导入 Maven项目 5 依赖管理5.1 使用坐标引入jar包5.2 依赖范围 Maven …

pytest的fixture梳理

fixture特性 可以重复使用&#xff0c;多个用例可以使用同一个fixture一个测试用例可以使用多个装置 import pytest # Arrange pytest.fixture def first_entry():return "a"# Arrange pytest.fixture def second_entry():return 2# Arrange pytest.fixture def or…

vscode搭建c语言环境问题

c语言环境搭建参考文章:【C语言初级阶段学习1】使用vscode运行C语言&#xff0c;vscode配置环境超详细过程&#xff08;包括安装vscode和MinGW-W64安装及后续配置使用的详细过程&#xff0c;vscode用户代码片段的使用&#xff09;[考研专用]_QAQshift的博客-CSDN博客 问题如下:…

FPGA外部触发信号毛刺产生及滤波

1、背景 最近在某个项目中&#xff0c;遇到输入给FPGA管脚的外部触发信号因为有毛刺产生&#xff0c;导致FPGA接收到的外部触发信号数量多于实际值。比如&#xff1a;用某个信号源产生1000个外部触发信号&#xff08;上升沿触发方式&#xff09;给到FPGA输入IO&#xff0c;实际…