从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 新闻合订本
    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 新闻合订本
    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • JavaSE

  • JavaSenior

  • JavaEE

    • JavaEE 概念

    • Ant

    • Maven

      • 什么是 Maven
      • 安装Maven
      • 第一个 Maven 项目
      • Maven 的组成和配置
      • 快速创建 Maven 项目
      • 创建 Web 项目
      • Maven 的生命周期和构建
      • Maven 的依赖管理
        • 配置 properties
        • 项目本身的坐标
        • 坐标的来源方式
        • 依赖范围 scope
        • 依赖冲突的问题
        • 锁定依赖版本
        • 查找依赖
        • 小结
      • Maven 的插件管理
      • IDEA 关于 Maven 的设置
      • 使用 Maven 完成 dao 层
      • 使用 Maven 完成 service 层
      • 使用 Maven 完成 web 层
      • Maven 的拆分和聚合
      • Nexus 的搭建
      • Nexus 的使用
      • 安装第三方 jar 包到私服
      • Maven 系列完结
    • 日志

    • Junit

    • JDBC

    • XML 和 JSON

  • JavaWeb

  • Spring

  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java
  • JavaEE
  • Maven
2023-05-15
目录

Maven 的依赖管理

# 45.Maven 的依赖管理

本文介绍关于依赖管理的更多概念

# 配置 properties

当我们需要用到的依赖多之后,一般会使用一个统一的版本,此时我们可以的配置可能是这样的:

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-web</artifactId>
	<version>5.0.2.RELEASE</version>
</dependency>

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>5.0.2.RELEASE</version>
</dependency>

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-tx</artifactId>
	<version>5.0.2.RELEASE</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

‍ 例如本例是使用 5.0.2.RELEASE。此时我们可能遇到这样的问题:升级版本。那么我们需要将所有涉及到的版本都改一遍!而我们可以通过配置 properties 的方式来简化配置:

<properties>
	<spring.version>5.0.2.RELEASE</spring.version>
</properties>
1
2
3

‍ 然后在用到的地方使用该 properties:这样就可以统一修改版本号了,其实这是 EL 表达式的一种。

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-web</artifactId>
	<version>${spring.version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>${spring.version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-tx</artifactId>
	<version>${spring.version}</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

‍ Maven 自己会有一些内置属性:

  • ${basedir} 项目根目录
  • ${project.build.directory} 构建目录,缺省为 target
  • ${project.build.outputDirectory} 构建过程输出目录,缺省为 target/classes
  • ${project.build.finalName} 产出物名称,缺省为 ${project.artifactId}-${project.version}
  • ${project.packaging} 打包类型,缺省为 jar
  • ${project.xxx} 当前 pom 文件的任意节点的内容 ‍

# 项目本身的坐标

每个 Maven 项目,都需要定义自己本身的坐标,例如本项目在 pom.xml 文件有这样的定义:

<!--项目名称,定义为组织名+项目名,类似包名-->
<groupId>com.peterjxl.LearnJavaMaven</groupId>

<!-- 模块名称 -->
<artifactId>hello-world</artifactId>

<!-- 当前项目版本号,snapshot 为快照版本即非正式版本,release 为正式发布版本 -->
<version>0.0.1-SNAPSHOT</version>
1
2
3
4
5
6
7
8

为什么项目也要定义坐标呢?因为项目本身也可以作为一个依赖,供其他项目使用!有很多开源项目,例如 Log4j 框架 (opens new window),其本身也是用 Maven 来管理的,也有引入其他依赖。

Maven 对依赖的分类:

  • 直接依赖:项目中直接导入的 jar 包,就是该项目的直接依赖包。
  • 传递依赖:项目中没有直接导入的 jar 包,也就是项目直接依赖的 jar 包所需要的依赖,这些依赖也是项目所需要的。

# 坐标的来源方式

添加依赖需要指定依赖 jar 包的坐标,但是很多情况我们是不知道 jar 包的的坐标,可以通过如下网址查询:

  • http://search.maven.org (opens new window)
  • http://mvnrepository.com (opens new window)
  • 还有很多网站提供类似的服务,不一一介绍了 ‍ 网站搜索示例:搜索 Spring

‍

然后就可以选择复制 Maven 的坐标,或者下载 JAR 文件

# 依赖范围 scope

A 依赖 B,需要在 A 的 pom.xml 文件中添加 B 的坐标, ‍ 添加坐标时需要指定依赖范围 <scope>,依赖范围包括:

  • compile:默认值,在编译、测试、打包和程序运行的时候需要用到的依赖
  • provided:只有在当 JDK 或者一个容器已提供该依赖之后才使用, provided 依赖在编译和测试时需要,在运行时不需要,比如:servlet 所用到的依赖,仅仅在编译时用到,在运行时,由于 Tomcat 已经有这些依赖了,因此在运行时不需要用到。
  • runtime:在运行和测试时需要,但在编译的时候不需要。比如 jdbc 的驱动包。由于运行时需要,所以 runtime 范围的依赖会被打包。
  • test:test 范围依赖 在编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用, 比如:junit。由于运行时不需要所以 test 范围依赖不会被打包。
  • system:system 范围依赖与 provided 类似,但是你必须显式的提供一个对于本地系统中 JAR 文件的路径,需要指定 systemPath 磁盘路径,system 依赖不推荐使用。 ‍ 我们可以列个表格:
依赖范围 对于编译 classpath 有效 对于测试 classpath 有效 对于运行时 classpath 有效 例子
compile Y Y Y Spring-Core
test - Y - Junit
provided Y Y - Servlet-api
Runtime - Y Y JDBC 驱动

‍

# 依赖冲突的问题

有时候,一个开源项目 A,会依赖于另一个开源项目 B;

而我们引入开源项目 A 的时候,Maven 会将项目 A,需要的依赖,也引入进来。例如,当我们引入 Spring 框架的时候:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
1
2
3
4
5

‍ 可以看到 Spring 还依赖于不少依赖:

‍

这样做有好处也有坏处:

  • 好处:引入一个依赖,就可以引入所有用到的依赖,不用一个一个的去引入
  • 坏处:当一个依赖 A,需要用到依赖 C;而另一个依赖 B,也用到依赖 C,并且需要的依赖 C 的版本还不同的时候... ‍ 我们可以演示下,添加一个新的依赖 spring-beans <:
 <dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.0.2.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.2.4.RELEASE</version>
    </dependency>
</dependencies>
1
2
3
4
5
6
7
8
9
10
11
12
13

虽然 spring-context 已经包含了 spring-beans <,但我们现在是为了演示问题,所以特地添加的。

我们可以通过 IDEA 来查看项目的依赖情况:首先打开 Maven 的工具面板,然后点击右上角的查看依赖关系(或者快捷键 Ctrl + Shift + Alt + U)

‍

我们可以看到,我们的项目的依赖情况,这里以一个网上的截图为例:

‍

由下往上看,我们的项目,使用了两个依赖:

  • spring-beans,其用到了一个依赖 spring-core
  • spring-context,其最后也是用到了 spring-core
  • 两者的版本是不一样的,最后到底用哪个呢?

我们可以看看 IDEA 的视图,可以看到最后用的还是 spring-core 5.0.2 的版本:

‍

但如果说我们将依赖的顺序调换下:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
11

‍ 此时,用的就是 4.2.4 的版本了!

因此我们引入依赖的时候,必须考虑如何解决。解决 jar 包冲突的方式:

  • 方式一:第一声明优先原则。哪个 jar 包的坐标在靠上的位置,这个 jar 包就是先声明的。先声明的 jar 包坐标下的依赖包,可以优先进入项目中。

  • 方式二:路径近者优先原则。直接依赖路径比传递依赖路径近,那么最终项目进入的 jar 包会是路径近的直接依赖包

  • 方式三【推荐使用】:直接排除法。当我们要排除某个 jar 包下依赖包,配置 exclusions 标签。内部可以不写版本号,因为此时依赖包使用的版本和默认和本 jar 包一样,例如本例中就是 spring-beans 的版本 4.2.4。

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.2.4.RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

# 锁定依赖版本

maven 工程是可以分父子依赖关系的。

凡是依赖别的项目后,拿到的别的项目的依赖包,都属于传递依赖。比如:当前 A 项目,被 B 项目依赖。那么我们 A 项目中所有 jar 包都会传递到 B 项目中。

B 项目开发者,如果再在 B 项目中导入一套 ssm 框架的 jar 包,对于 B 项目是直接依赖,那么直接依赖的 jar 包就会把我们 A 项目传递过去的 jar 包覆盖掉。

为了防止以上情况的出现。我们可以把 A 项目中主要 jar 包的坐标锁住,那么其他依赖该项目的项目中,即便是有同名 jar 包直接依赖,也无法覆盖。

配置方法:使用 <dependencyManagement> 标签

<dependencyManagement>
  <dependencies>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>${mybatis.version}</version>
    </dependency>

  </dependencies>
</dependencyManagement>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

‍ 注意,锁定的 jar 包仅仅是锁定作用,并没有引入依赖。

# 查找依赖

有时候我们知道类名,但是不知道对应的 Maven 依赖,也可以通过搜索来找到。

打开 https://search.maven.org/

一. 已知全类名:输入 fc: org.apache.poi.xssf.usermodel.XSSFWorkbook (注:fc 代表 full class)

二. 已知类名:输入 c: 类名(注:c 代表 class)

三. 已知 Group ID 或者 Artifact ID,g: com.alibaba a: druid ‍

# 小结

我们讲了什么是依赖,并且介绍了 scope 和依赖冲突的方式,下一篇我们来讲讲插件管理。

上次更新: 2025/6/3 09:31:54
Maven 的生命周期和构建
Maven 的插件管理

← Maven 的生命周期和构建 Maven 的插件管理→

最近更新
01
新闻合订本 2025-10
10-31
02
2025 年 10 月记
10-30
03
用 AI 批量优化思源笔记排版
10-15
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式