【Maven系列3】坐标与依赖
主要讲解Maven的依赖管理相关知识。前言Maven确实比较简单估计大家在工作期间每天抽出一点时间基础部分几天就可以学完所以这块感觉真没有啥好讲的。这篇文章先讲解依赖管理的基础知识然后再结合一个简单的示例消耗一下。基础知识坐标类比为数学中平面几何坐标x、y 任何一个坐标都能唯一标识该平面中的一个点。该点对应到 maven 就是 .jar、.war 等文件的文件。Maven 使用 groupId、artifactId、version、packaging、classifier 等元素来组成自己的坐标并定义一组这样的规则只要能提供正确坐标元素 Maven 就能找到对应的构件。坐标元素groupId定义当前 Maven 项目隶属的实际项目。artifactId定义实际项目中的一个 Maven 项目模块。packaging定义 Maven 项目打包方式。jar、war、pom。默认为 jar。version定义 Maven 项目当前所处的版本。classifier区分从同一 artifact 构建的具有不同内容的构件。比如我经常用的示例project ... groupIdorg.example/groupId artifactIddemo5/artifactId version1.0-SNAPSHOT/version packagingwar/packaging ... /project构件名与坐标是对应的一般规则是artifactId-version[-classifier].packaging。依赖声明project ... dependencies dependency groupId实际项目/groupId artifactId模块/artifactId version版本/version type依赖类型/type scope依赖范围/scope optional依赖是否可选/optional !—主要用于排除传递性依赖-- exclusions exclusion groupId…/groupId artifactId…/artifactId /exclusion /exclusions /dependency dependencies ... /projectgroupId、artifactId、version依赖的基本坐标。type依赖的类型对应项目对应的 packaging一般不必声明。scope依赖的范围后面详解。optional标记依赖是否可选。exclusions用来排除传递性依赖。依赖范围依赖范围就是用来控制依赖和三种classpath(编译classpath测试classpath、运行classpath)的关系Maven有如下几种依赖范围**compile:**编译依赖范围。如果没有指定就会默认使用该依赖范围。使用此依赖范围的Maven依赖对于编译、测试、运行三种classpath都有效。典型的例子是spring-code,在编译、测试和运行的时候都需要使用该依赖。test: 测试依赖范围。使用次依赖范围的Maven依赖只对于测试classpath有效在编译主代码或者运行项目的使用时将无法使用此依赖。典型的例子是Jnuit,它只有在编译测试代码及运行测试的时候才需要。**provided:**已提供依赖范围。使用此依赖范围的Maven依赖对于编译和测试classpath有效但在运行时候无效。典型的例子是servlet-api,编译和测试项目的时候需要该依赖但在运行项目的时候由于容器已经提供就不需要Maven重复地引入一遍。**runtime:**运行时依赖范围。使用此依赖范围的Maven依赖对于测试和运行classpath有效但在编译主代码时无效。典型的例子是JDBC驱动实现项目主代码的编译只需要JDK提供的JDBC接口只有在执行测试或者运行项目的时候才需要实现上述接口的具体JDBC驱动。**system:**系统依赖范围。该依赖与三种classpath的关系和provided依赖范围完全一致但是使用system范围的依赖时必须通过systemPath元素显示地指定依赖文件的路径。由于此类依赖不是通过Maven仓库解析的而且往往与本机系统绑定可能构成构建的不可移植因此应该谨慎使用。systemPath元素可以引用环境变量如dependency groupIdjavax.sql/groupId artifactIdjdbc-stdext/artifactId Version2.0/Version scopesystem/scope systemPath${java.home}/lib/rt.jar/systemPath /dependency**import:**导入依赖范围。只在 dependencyManagement 标签中生效导入已经定义好的 pom 文件中该依赖范围不会对三种classpath产生实际的影响。dependencyManagement dependencies dependency groupIdorg.springframework/groupId artifactIdspring-framework-bom/artifactId version4.3.16.RELEASE/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement这个干啥用呢what上述除import以外的各种依赖范围与三种classpath的关系如下:开始还不太明白这个“依赖范围”是啥意思其实就是在编译、测试、运行时的3个环节虽然在pom.xml中配置了依赖项但是有些依赖项只对某几个环节生效对有些环节其实是不生效的。依赖机制与特性传递性依赖比如一个account-email项目为例account-email有一个compile范围的spring-code依赖spring-code有一个compile范围的commons-logging依赖那么commons-logging就会成为account-email的compile的范围依赖commons-logging是account-email的一个传递性依赖。假设A依赖于B,B依赖于C我们说A对于B是第一直接依赖B对于C是第二直接依赖A对于C是传递性依赖。第一直接依赖和第二直接依赖的范围决定了传递性依赖的范围如下图所示最左边一行表示第一直接依赖范围最上面一行表示第二直接依赖范围中间的交叉单元格则表示传递依赖范围。从上图中我们可以发现这样的规律当第二直接依赖的范围是compile的时候传递性依赖的范围与第一直接依赖的范围一致当第二直接依赖的范围是test的时候依赖不会得以传递当第二直接依赖的范围是provided的时候只传递第一直接依赖范围也为provided的依赖切传递依赖的范围同样为provided当第二直接依赖的范围是runtime的时候传递性依赖的范围与第一直接依赖的范围一致但compile列外此时传递性依赖范围为runtime。依赖调解当传递性依赖出现问题时能够清楚地知道该传递性依赖是从哪条依赖路径中引入的。路径最近者优先原则A-B-C-X(1.0)A-D-X(2.0)第一声明者优先原则A-B-Y(1.0)A-C-Y(2.0)此时由于依赖路径长度一致按照第一声明者优先原则。在路径长度一致的前提下如果 B 依赖在 POM 文件中声明顺序在 C 依赖之前那么 Y(1.0) 则会被引入。但是如果你在同一个文件中这么写dependencies dependency groupIdcommons-codec/groupId artifactIdcommons-codec/artifactId version1.11/version /dependency dependency groupIdcommons-codec/groupId artifactIdcommons-codec/artifactId version1.10/version /dependency /dependencies如果有需要依赖commons-codec得到的是1.11不是1.10可以这么理解依赖调解只发生于构建来自不同 pom 时而此时构建声明处于同一 pom故不会触发依赖调解。可选依赖如图项目中A依赖BB依赖于X和Y如果所有这三个的范围都是compile的话那么X和Y就是A的compile范围的传递性依赖但是如果我想X,Y不作为A的传递性依赖不给他用的话可以通过optional为true配置为可选依赖。project modelVersion4.0.0/modelVersion groupIdcom.juvenxu.mvnbook/groupId artifactIdproject-b/artifactId version1.0.0/version dependencies dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version5.1.10/version optionaltrue/optional /dependency dependency groupIdpostgresql/groupId artifactIdpostgresql/groupId version8.4-701.jdbc3/version optionaltrue/optional /dependency /dependencies /project排除依赖有时候你引入的依赖中包含你不想要的依赖包你想引入自己想要的这时候就要用到排除依赖了比如下图中spring-boot-starter-web自带了logback这个日志包我想引入log4j2的所以我先排除掉logback的依赖包再引入想要的包就行了。这里注意声明exclustion的时候只需要groupId和artifactId而不需要version元素这是因为只需要groupId和artifactId就能唯一定位依赖图中的某个依赖。依赖示例通常情况下在一个共通的项目下有一系列的项目。在这种情况下我们可以创建一个公共依赖的 pom 文件该 pom 包含所有的公共的依赖关系我们称其为其他子项目 pom 的 pom 父。接下来的一个例子可以帮助你更好的理解这个概念。接下来是上面依赖图的详情说明App-UI-WAR 依赖于 App-Core-lib 和 App-Data-lib。Root 是 App-Core-lib 和 App-Data-lib 的父项目。Root 在它的依赖部分定义了 Lib1、lib2 和 Lib3 作为依赖。App-UI-WAR 的 pom.xml 文件代码如下project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion groupIdcom.companyname.groupname/groupId artifactIdApp-UI-WAR/artifactId version1.0/version packagingwar/packaging dependencies dependency groupIdcom.companyname.groupname/groupId artifactIdApp-Core-lib/artifactId version1.0/version /dependency /dependencies dependencies dependency groupIdcom.companyname.groupname/groupId artifactIdApp-Data-lib/artifactId version1.0/version /dependency /dependencies /projectApp-Core-lib 的 pom.xml 文件代码如下project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd parent artifactIdRoot/artifactId groupIdcom.companyname.groupname/groupId version1.0/version /parent modelVersion4.0.0/modelVersion groupIdcom.companyname.groupname/groupId artifactIdApp-Core-lib/artifactId version1.0/version packagingjar/packaging /projectApp-Data-lib 的 pom.xml 文件代码如下project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd parent artifactIdRoot/artifactId groupIdcom.companyname.groupname/groupId version1.0/version /parent modelVersion4.0.0/modelVersion groupIdcom.companyname.groupname/groupId artifactIdApp-Data-lib/artifactId version1.0/version packagingjar/packaging /projectRoot 的 pom.xml 文件代码如下project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion groupIdcom.companyname.groupname/groupId artifactIdRoot/artifactId version1.0/version packagingpom/packaging dependencies dependency groupIdcom.companyname.groupname1/groupId artifactIdLib1/artifactId version1.0/version /dependency /dependencies dependencies dependency groupIdcom.companyname.groupname2/groupId artifactIdLib2/artifactId version2.1/version /dependency /dependencies dependencies dependency groupIdcom.companyname.groupname3/groupId artifactIdLib3/artifactId version1.1/version /dependency /dependencies /project现在当我们构建 App-UI-WAR 项目时 Maven 将通过遍历依赖关系图找到所有的依赖关系并且构建该应用程序。公共的依赖可以使用 pom 父的概念被统一放在一起。App-Data-lib 和 App-Core-lib 项目的依赖在 Root 项目里列举了出来参考 Root 的包类型它是一个 POM.没有必要在 App-UI-W 里声明 Lib1, lib2, Lib3 是它的依赖。Maven 通过使用可传递的依赖机制来实现该细节。

相关新闻

【MyBatis系列1】基础知识(上)

【MyBatis系列1】基础知识(上)

主要讲解 MyBatis 的基础知识前言上个月完成了“Java 并发编程系列”和“Spring 基础系列”知识的学习,这个月我们主要学习 MyBatis。MyBatis 网上的资料真的非常多,整个知识体系也非常系统,如果要整体学完,需要花很多时间&#x…

2026/9/26 21:00:50 阅读更多 →
【MyBatis系列2】MyBatis与Spring整合

【MyBatis系列2】MyBatis与Spring整合

通过示例讲解MyBatis和Spring整合的流程。前言这个MyBatis和Spring整合示例,是我今年3月份刚转岗时需要熟悉MyBatis时写的,主要是想知道项目是如何从0到1,在Spring中用到MyBatis。这个示例是参考“C语言中文网”,但是里面的示例不…

2026/9/26 21:03:54 阅读更多 →
生猪运输流向智能分析系统:让每一车猪都“来路可查、去向可追”

生猪运输流向智能分析系统:让每一车猪都“来路可查、去向可追”

生猪调运是养猪产业链的“大动脉”——全国每年跨省调运生猪数亿头次,一辆9.6米高栏车就能装150头猪,一趟行程连接的是养殖场、贩运商、屠宰场三个环节。可这条动脉的“血流方向”,长期处于“看不清、管不住”的状态:猪从哪里来、…

2026/9/25 18:28:19 阅读更多 →

最新新闻

DeskcommCRM系统设计与落地实践:从坐席台到客户全生命周期管理

DeskcommCRM系统设计与落地实践:从坐席台到客户全生命周期管理

直接说结论:DeskcommCRM 这个名字,第一眼看上去像是某个企业自研的客户管理系统代号,但拆开来看就很有意思。Desk 代表桌面作业场景,comm 是 communication 的缩写,强调沟通能力,后面的 CRM 才是客户关系管…

2026/9/26 21:03:43 阅读更多 →
全国30m土地利用数据实战:从坐标投影到变化检测的Python全链路

全国30m土地利用数据实战:从坐标投影到变化检测的Python全链路

简介:这份资源为2018年全国土地利用30米分辨率遥感数据,面向GIS、遥感、城乡规划、生态环保等方向的研究人员与学生,用于土地覆盖分类、时空变化分析与制图实践。数据以30米栅格像元刻画耕地、林地、草地、建设用地、水域等地类,遵…

2026/9/26 21:03:43 阅读更多 →
SpringBoot+Vue实现城市轨道交通安全管理系统:闭环、权限与可视化

SpringBoot+Vue实现城市轨道交通安全管理系统:闭环、权限与可视化

毕设选了《基于SpringBootVue的城市轨道交通安全管理系统》,十个同学里八个第一反应是同一个问题:这不就是一个后台管理CRUD加上几张统计图表吗?说实话,做之前我也这么想,直到把应急预案、隐患排查、巡检整改这些流程真…

2026/9/26 21:03:43 阅读更多 →
Navicat for MySQL 10.1.7 绿色中文版原理与实战指南

Navicat for MySQL 10.1.7 绿色中文版原理与实战指南

简介:本资源为Navicat for MySQL 10.1.7绿色中文版完整安装包,面向数据库初学者、运维人员及开发工程师,解决MySQL可视化管理工具的快速部署与本地化使用需求,无需安装即可运行,特别适合离线环境或权限受限的开发测试场…

2026/9/26 21:03:43 阅读更多 →
Agent-native实战:让AI代理真正能调用你的业务系统

Agent-native实战:让AI代理真正能调用你的业务系统

把大模型接到一个真实业务系统时,我第一反应是“对话框一放,问题不大”。可真做起“让AI代理自动完成一单操作”时,才发现完全不是这么回事。系统有界面、有接口、有数据,但代理进去之后四处碰壁——不是模型笨,而是这…

2026/9/26 21:03:43 阅读更多 →
NVMe全闪存储阵列选型与性能调优实战指南

NVMe全闪存储阵列选型与性能调优实战指南

1. 为什么2026年大家都在追NVMe全闪存储阵列过去一年多,我陆续帮几个团队做过存储方案选型和落地,一个是搞AI大模型训练的,一个是做芯片前端验证的,还有一个是影视后期的工作室。他们碰到的瓶颈出奇一致——计算资源早就堆上去了&…

2026/9/26 21:02:43 阅读更多 →

日新闻

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、…

2026/9/26 0:00:25 阅读更多 →
学校官网模拟全流程实践:从页面布局到后端接口与部署

学校官网模拟全流程实践:从页面布局到后端接口与部署

如果你正在找一门 Web 大作业的题目,或者刚开始接触 Web 前端开发想做点能拿来展示的东西,“学校官网模拟”几乎是最稳的选择。题目看着简单,但要把导航、新闻列表、轮播 Banner、二级页面、后台数据都串起来,其实已经把前端布局、…

2026/9/26 0:00:25 阅读更多 →
超级玛丽游戏源码C++:从零搭建横版跳跃游戏工程

超级玛丽游戏源码C++:从零搭建横版跳跃游戏工程

简介:这是一份面向游戏开发初学者与C进阶学习者的超级玛丽(超级马里奥)游戏源码,基于C面向对象编程实现,适合想通过经典项目理解游戏主循环、角色类设计、地图关卡加载与物理碰撞检测的读者参考。压缩包共49个文件&…

2026/9/26 0:00:25 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/25 19:27:14 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/26 20:27:29 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/25 20:29:09 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/25 20:29:43 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/25 20:29:31 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/25 19:27:26 阅读更多 →