【Maven系列3】坐标与依赖

发布时间:2026/9/25 18:28:23

【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 通过使用可传递的依赖机制来实现该细节。
延伸阅读

更多相关文章

2026/9/25 18:28:23

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

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

2026/9/25 18:28:23

【MyBatis系列2】MyBatis与Spring整合

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

2026/9/25 18:28:23

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

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

2026/9/25 20:58:30

AVFoundation视频开发核心:CMTime坐标系与AVPlayerItem状态机

1. 为什么AVFoundation不是“另一个播放器SDK”,而是iOS/macOS视频能力的底层操作系统很多人第一次接触AVFoundation,是在Xcode里拖一个AVPlayerViewController进Storyboard,调用几行代码就播出了MP4——然后理所当然地认为:“哦&…

2026/9/25 20:58:30

UE5 GeometryCore 实战:FDynamicMesh3 动态网格操作与性能优化指南

1. 从“能跑就行”到“几何可控”:GeometryCore 到底在解决什么问题如果你在 UE5 里做过程序化建模、动态切割、地形雕刻或者运行时网格变形,大概率经历过这样的场景:蓝图里拖了一堆 ProceduralMeshComponent 节点,跑起来帧率直接…

2026/9/25 20:58:29

原生PHP论坛开发实战:从登录到部署的完整安全指南

简介:这是一套基于PHP构建的简单Web论坛源码包,面向PHP初学者与教学场景,以论坛这一交互性较强的应用为载体,演示动态网站的开发思路。压缩包共28个文件、约266KB,包含10个PHP核心脚本、11个GIF界面元素、3张JPG设计图…

2026/9/25 20:58:29

PHP在线生成查询产品防伪证书系统:防伪码生成与查询链路详解

简介:PHP在线生成查询产品防伪证书系统源码.zip是一套面向企业及开发者的防伪证书生成与查询解决方案,适用于搭建产品防伪验证平台。源码基于PHPMYSQL开发,需使用PHP5.1~5.3环境,压缩包内自带90套授权证书模板及PSD公章源文件&…

2026/9/25 20:58:29

HTTP 实操手册:状态码排查、连接复用与嵌入式客户端

这篇文章写在旧站归档之际。熟悉我的朋友应该已经注意到,原来那个站点已经有一阵子没动静了。这段时间我在做一件听起来枯燥但很必要的事:把过去几年分散在各处的文章、代码片段和笔记重新整理一遍,后续新内容会统一放到 www.52brt.com 持续更…

2026/9/25 21:00:17

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/25 20:59:52

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/25 0:02:35

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:02:35

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:02:35

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 20:55:38

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/25 18:41:36

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/25 18:34:56

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑