Maven 依赖管理与依赖标签
原文链接
1.概述
在本教程中,我们将回顾两个重要的Maven标签——dependencyManagement 和 dependencies。
这些特性对于多模块项目特别有用。
我们将回顾这两个标签的相同点和不同点,我们还将研究开发人员在使用它们时常犯的一些可能导致混淆的错误。
2.用法
通常,当我们在dependencies标签中定义我们的依赖时,我们使用dependencyManagement标签来避免重复版本和范围 标签。通过这种方式,所需的依赖项在中央 POM 文件中声明。
2.1. 依赖管理
这个标签由一个dependencies标签组成,它本身可能包含多个dependency标签。每个依赖项应该至少有三个主要标签:groupId、artifactId和version。让我们看一个例子:
<dependencyManagement><dependencies><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency></dependencies>
</dependencyManagement>
上面的代码只是声明了新的工件commons-lang3,并没有真正将其添加到项目依赖资源列表中。
2.2. 依赖关系
此标记包含依赖项标记列表。每个依赖 项应该至少有两个主要标签,即groupId 和artifactId。
让我们看一个简单的例子:
<dependencies><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency>
</dependencies>
如果我们之前在 POM 文件中使用过dependencyManagement 标签,则可以隐式继承版本和范围标签:
<dependencies><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency>
</dependencies>
3.相似之处
这两个标签都旨在声明一些第三方或子模块依赖性。它们相辅相成。
事实上,我们通常在 dependencies 标签之前定义一次dependencyManagement标签。这用于在 POM 文件中声明依赖关系。这个声明只是一个公告,并没有真正给项目添加依赖。
让我们看一个添加 JUnit 库依赖项的示例:
<dependencyManagement><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency></dependencies>
</dependencyManagement>
正如我们在上面的代码中看到的,有一个dependencyManagement标签本身包含另一个dependencies标签。
现在,让我们看看代码的另一面,它将实际的依赖项添加到项目中:
<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency>
</dependencies>
因此,当前标签与前一个标签非常相似。它们都将定义一个依赖项列表。当然,我们很快就会介绍一些小的差异。
两个代码片段中重复了相同的groupId和artifactId标签,它们之间存在有意义的相关性:它们都指向同一个工件。
正如我们所看到的,我们后面的依赖标签中没有任何版本标签。令人惊讶的是,它是有效的语法,并且可以毫无问题地进行解析和编译。原因很容易猜到:它会使用dependencyManagement声明的版本。
4. 差异
4.1. 结构差异
正如我们之前介绍的,这两个标签之间的主要结构差异是继承逻辑。我们在dependencyManagement标签中定义版本,然后我们可以使用提到的版本而无需在下一个dependencies标签中指定它。
4.2. 行为差异
dependencyManagement只是一个声明,并没有真正添加依赖。此部分中声明的依赖项必须稍后由dependencies标记使用。导致真正依赖发生的只是dependencies标签。在上面的示例中, dependencyManagement标记不会将junit库添加到任何范围。它只是未来依赖 标记的声明。
5.真实世界的例子
几乎所有基于 Maven 的开源项目都使用这种机制。
让我们看一个Maven 项目本身的例子。我们看到了hamcrest-core依赖,它存在于 Maven 项目中。它首先在dependencyManagement 标签中声明,然后由主依赖标签导入:
<dependencyManagement><dependencies><dependency><groupId>org.hamcrest</groupId><artifactId>hamcrest-core</artifactId><version>2.2</version><scope>test</scope></dependency></dependencies>
</dependencyManagement><dependencies><dependency><groupId>org.hamcrest</groupId><artifactId>hamcrest-core</artifactId><scope>test</scope></dependency>
</dependencies>
6. 常见用例
此功能的一个非常常见的用例是多模块项目。
想象一下,我们有一个由不同模块组成的大项目。每个模块都有自己的依赖项,每个开发人员可能会为使用的依赖项使用不同的版本。然后它可能导致不同工件版本的网格,这也可能导致难以解决的冲突。
这个问题的简单解决方案肯定是在根 POM 文件(通常称为“父”)中使用dependencyManagement标签,然后在子 POM 文件(子模块)甚至父模块本身(如果适用)中使用依赖项.
如果我们只有一个模块,使用这个特性是否有意义?尽管这在多模块环境中非常有用,但即使在单模块项目中,也可以将其作为最佳实践遵守。这有助于提高项目的可读性,并使其准备好扩展到多模块项目。
7. 常见错误
一个常见的错误是仅在dependencyManagement部分中定义依赖项,而不将其包含在dependencies标记中。在这种情况下,我们会遇到编译或运行时错误,具体取决于提到的范围。
让我们看一个例子:
<dependencyManagement><dependencies><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency>...</dependencies>
</dependencyManagement>
想象一下上面的 POM 代码片段。然后假设我们要在子模块源文件中使用这个库:
import org.apache.commons.lang3.StringUtils;public class Main {public static void main(String[] args) {StringUtils.isBlank(" ");}
}
由于缺少库,此代码将无法编译。编译器报错:
[ERROR] Failed to execute goal compile (default-compile) on project sample-module: Compilation failure
[ERROR] ~/sample-module/src/main/java/com/baeldung/Main.java:[3,32] package org.apache.commons.lang3 does not exist
为避免此错误,将以下依赖项 标记添加到子模块 POM 文件中就足够了:
<dependencies><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency>
</dependencies>
8、结论
在本教程中,我们比较了 Maven 的dependencyManagement和dependencies标签。然后,我们回顾了它们的异同,并了解了它们如何协同工作。
Maven 依赖管理与依赖标签相关推荐
- 4.Maven概念模型,maven的生命周期,Maven坐标,依赖管理(依赖范围,依赖声明),仓库管理,私服概念
1 maven概念模型 2 maven的生命周期,项目构建过程 Maven生命周期就是为了对所有的构建过程进行抽象和统一 包括项目清理,初始化,编译,打包,测试,部署等几乎所有构建步骤 Mave ...
- maven依赖管理_依赖管理和Maven
maven依赖管理 Maven伟大而成熟. 几乎所有事物都总有解决方案. 您可能在组织项目上遇到的主要情况是依赖管理. 而不是每个项目都具有自己的依赖关系,您需要一种集中的方式来继承那些依赖关系. 在 ...
- maven java管理_java – 依赖管理与maven
我最近成了Maven的大粉丝,用于控制我的应用程序的构建周期.然而,我遇到了一些粗暴的边缘与Maven的依赖管理.我想知道这些是否是工具和范例的限制,依赖管理的必要的邪恶,或者我是否使用错误的工具. ...
- maven依赖管理(依赖配置、依赖传递、依赖冲突、依赖范围)
文章目录 基本说明 依赖配置 依赖传递 直接依赖 间接依赖 依赖冲突 路径优先 声明优先 特殊依赖 可选依赖 排除依赖 可选依赖和排除依赖区别 依赖范围 总结 基本说明 这篇文章会介绍在maven中的 ...
- 配置所需要的依赖_Maven依赖管理之依赖传递
1 传递依赖 2.1 什么是传递依赖 当A 依赖B.B依赖C,在A中导入B后会自动导入C,C是A的传递依赖,如果C依赖D则D也可能是A的传递依赖. 演示: web中添加struts-spring的ja ...
- gradle依赖管理_依赖管理
gradle依赖管理 Why Bother 何必呢 Writing software is a very expensive process, and most systems we interact ...
- 【Android Gradle 插件】Android 依赖管理 ④ ( 常用依赖配置分析 | implementation 依赖作用 | api 依赖作用 | compileOnly 依赖作用 )
文章目录 一.compile 依赖作用 二.implementation 依赖作用 三.api 依赖作用 四.compileOnly 依赖作用 五.annotationProcessor 依赖作用 六 ...
- Maven安装和依赖管理详解
文章目录 Maven相关的概念 Maven仓库和坐标 Maven的安装 IDEA集成Maven 使用IDEA创建Maven工程 Maven的常用命令 依赖管理 Maven相关的概念 maven 资源仓 ...
- 关于 C++ 依赖管理
有经验的程序员,不论所用何种语言,对代码依赖都不会陌生.代码无论是依赖于内部依赖关系,还是依赖于外部库或框架,通常都不会孤立运行.代码的重复使用,亦即使用现有代码的做法,是提升开发效率的重要工具.不过 ...
最新文章
- java 中的内部类学习小记
- 【采用】【风险管理】(第三篇)风险管理报表体系
- WEB前端 Vue 全家桶介绍
- linux安装卸载mysql,Linux6 系列 安装、卸载mysql
- 上海理工大学菜鸟驿站把无人车送进社区 协助解决抗疫物资“最后100米”配送...
- Mysql 存储类型范围
- 微信小程序Demo大全
- 基于北京二手房价数据的探索性数据分析和房价评估——房价评估模型构建
- 旅游展示网站-前端网页设计技术完整精美源码HTML+CSS+JS
- Ubuntu18.04安装PX4并与ROS联合实验
- python评分卡模型
- 在线购物系统 问题描述、词汇表、领域类图
- html中的定位及其定位方式
- 安卓蓝牙SCO打开流程
- 服务器错误信息36887,TLS 协议所定义的严重错误代码是 10。Windows SChannel 错误状态是 1203...
- MySQL基础篇3——DDL、DML、DCL使用篇
- NBMA和BMA的交换方式
- 华红兵:移动互联网时代,场景理论的四大特征
- python画k线图_一步一步教你用Python画出专业的K线图
- 工作总结12 ADMU7704E: 在尝试启动与服务器相关联的 Windows 服务时失败:server1