Maven的依赖管理
1. 依赖管理
依赖管理,可以将有关依赖项的所有信息放在共同的POM中,并对子POM中的工件进行更简单的引用。举个例子:
父POM
<project>......<dependencyManagement><dependencies><dependency><groupId>group-a</groupId><artifactId>artifact-a</artifactId><version>1.0</version><exclusions><exclusion><groupId>group-c</groupId><artifactId>excluded-artifact</artifactId></exclusion></exclusions></dependency><dependency><groupId>group-c</groupId><artifactId>artifact-b</artifactId><version>1.0</version><type>war</type><scope>runtime</scope></dependency><dependency><groupId>group-a</groupId><artifactId>artifact-b</artifactId><version>1.0</version><type>bar</type><scope>runtime</scope></dependency></dependencies></dependencyManagement>......
</project>
两个子POM
<project>...<dependencies><dependency><groupId>group-a</groupId><artifactId>artifact-a</artifactId></dependency><dependency><groupId>group-a</groupId><artifactId>artifact-b</artifactId><!-- This is not a jar dependency, so we must specify type. --><type>bar</type></dependency></dependencies>
</project><project>...<dependencies><dependency><groupId>group-c</groupId><artifactId>artifact-b</artifactId><!-- This is not a jar dependency, so we must specify type. --><type>war</type></dependency><dependency><groupId>group-a</groupId><artifactId>artifact-b</artifactId><!-- This is not a jar dependency, so we must specify type. --><type>bar</type></dependency></dependencies>
</project>
在<dependencyManagement>区域,实际上是根据{groupId, artifactId, type, classifier}来进行依赖匹配的。自从<type>字段的默认值是jar以后,最简单的标识只需要设置{groupId, artifactId}即可。
依赖管理的另一个重要的作用是统一管理(控制)依赖的版本。这一点不再赘述。
2. 导入依赖
依赖可以继承,但是目前只支持单继承,可以通过“import”的方式从其它POM中导入依赖。
下面的例子,Z导入了X和Y管理的依赖。
<project><modelVersion>4.0.0</modelVersion><groupId>maven</groupId><artifactId>Z</artifactId><packaging>pom</packaging><version>1.0</version><dependencyManagement><dependencies><dependency><groupId>maven</groupId><artifactId>X</artifactId><version>1.0</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>maven</groupId><artifactId>Y</artifactId><version>1.0</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
</project>
举个例子
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.example</groupId><artifactId>demo-parent</artifactId><version>0.0.1-SNAPSHOT</version></parent><groupId>com.example</groupId><artifactId>demo001</artifactId><version>0.0.1-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.7.11</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>
3. 版本管理插件
Introduction – Versions Maven Plugin
versions插件用于管理、模块、依赖和插件的版。该插件有很多目标,为了统一管理父子项目版本号,我们这里只用其中三个。
操作很简单,首先,在父工程中引入versions插件
<!-- 父POM中增加插件 -->
<build><plugins><plugin><groupId>org.codehaus.mojo</groupId><artifactId>versions-maven-plugin</artifactId><version>2.16.2</version><configuration><generateBackupPoms>false</generateBackupPoms></configuration></plugin></plugins>
</build>
然后,更新父工程的版本号
mvn versions:set -DnewVersion="2.0.0-SNAPSHOT" //更新整个项目版本
接着,把子模块的版本更新成父工程的版本号
mvn versions:update-child-modules

最后提交
mvn versions:commit


4. BOM
对于一个项目来说,使用“库”中的一个或多个构件是相当常见的。为了使项目中使用的构件的版本与库中分发的版本保持同步。我们可以创建一个“物料清单”(BOM)以供其它项目使用。
简单的来讲,就是多个项目都需要依赖某些包时,为了方便管理版本,使得多个项目中引用的某个包的版本保持一致,这个时候我们就定义一个“库”,在这个库中统一定义包的版本,使用的时候只需要导入这个库即可。
举个例子:
定义一个库(其实就是一个POM)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.test</groupId><artifactId>mytest-bom</artifactId><version>1.0.0</version><packaging>pom</packaging><properties><project1Version>1.0.0</project1Version><project2Version>1.0.0</project2Version></properties><dependencyManagement><dependencies><dependency><groupId>com.test</groupId><artifactId>project1</artifactId><version>${project1Version}</version></dependency><dependency><groupId>com.test</groupId><artifactId>project2</artifactId><version>${project2Version}</version></dependency></dependencies></dependencyManagement>
</project>
然后,定义两个项目project1和project2
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.test</groupId><artifactId>mytest-bom</artifactId><version>1.0.0</version></parent><groupId>com.test</groupId><artifactId>parent</artifactId><version>1.0.0</version><packaging>pom</packaging><dependencyManagement><dependencies><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.22.0</version></dependency></dependencies></dependencyManagement></project>
project1
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.test</groupId><artifactId>parent</artifactId><version>1.0.0</version></parent><groupId>com.test</groupId><artifactId>project1</artifactId><version>${project1Version}</version><packaging>jar</packaging><dependencies><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId></dependency></dependencies>
</project>
project2
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.test</groupId><artifactId>parent</artifactId><version>1.0.0</version></parent><groupId>com.test</groupId><artifactId>project2</artifactId><version>${project2Version}</version><packaging>jar</packaging>
</project>
最后,在其它项目中引用project1和project2
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.test</groupId><artifactId>use</artifactId><version>1.0.0</version><packaging>jar</packaging><dependencyManagement><dependencies><dependency><groupId>com.test</groupId><artifactId>mytest-bom</artifactId><version>1.0.0</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>com.test</groupId><artifactId>project1</artifactId></dependency><dependency><groupId>com.test</groupId><artifactId>project2</artifactId></dependency></dependencies>
</project>
可以看到,使用的时候,直接导入这个POM,然后按需引用

核心就是在一个公共的pom中定义包的版本和依赖管理,然后在使用的时候导入公共pom
假设现在在做一个项目,其中有两个子项目,在cjs-store-service中需要引用cjs-workflow-provider-api
先定义一个公共的pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>cjs-dependencies-bom</artifactId><version>1.0.0-SNAPSHOT</version><packaging>pom</packaging><properties><store.version>0.0.4-SNAPSHOT</store.version><workflow.version>0.0.3-SNAPSHOT</workflow.version></properties><dependencyManagement><dependencies><dependency><groupId>com.example</groupId><artifactId>cjs-store-provider-api</artifactId><version>${store.version}</version></dependency><dependency><groupId>com.example</groupId><artifactId>cjs-workflow-provider-api</artifactId><version>${workflow.version}</version></dependency></dependencies></dependencyManagement></project>
项目中引用
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.example</groupId><artifactId>cjs-store</artifactId><version>0.0.4-SNATHOST</version></parent><groupId>com.example</groupId><artifactId>cjs-store-service</artifactId><version>0.0.4-SNATHOST</version><dependencies><dependency><groupId>com.example</groupId><artifactId>cjs-store-dto</artifactId><version>${project.parent.version}</version></dependency><dependency><groupId>com.example</groupId><artifactId>cjs-workflow-provider-api</artifactId></dependency></dependencies><!-- 如果父工程cjs-store的parent不是cjs-dependencies-bom,则这里需要import,否则不需要,因为可以直接通过继承得到 --><dependencyManagement><dependencies><dependency><groupId>com.example</groupId><artifactId>cjs-dependencies-bom</artifactId><version>1.0.0-SNAPSHOT</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
</project>
其实,这种依赖包管理可以学习一下dubbo

5. 项目启动问题
如果你的springboot项目起不来,控制台也不打印任何报错信息,就像这样

那么,你可以在SpringApplication.run()这一行打断点

然后,就可以看到报错了

相关文章:
Maven的依赖管理
1. 依赖管理 依赖管理,可以将有关依赖项的所有信息放在共同的POM中,并对子POM中的工件进行更简单的引用。举个例子: 父POM <project>......<dependencyManagement><dependencies><dependency><groupId>gro…...
数据结构考前一天
线性表:矩阵,链表(单链表必考) 栈和队列:出入判断,括号匹配,中缀转后缀 字符串数组:模式匹配next,nextval数组,数组寻址,三角矩阵对应一维数组k…...
获取 Astro Bot AI 语音来增强您的游戏体验!
有很多用户尝试过Astro Bot,却被Astro Bot可爱的声音所吸引。您是否想知道如何使用 Astro Bot 语音来拨打恶作剧电话或用他的声音说话?如果您有,那么这篇文章适合您。我们将向您展示如何为 Astro Bot 提供逼真的 AI 声音并在在线对话中使用它…...
html5开发,js 在元素div id=img1的最前面插入一个图片
在 JavaScript 中,你可以使用 document.createElement 来创建一个新的图片元素,然后使用 document.getElementById 来获取目标 div 元素,并使用 appendChild 方法将新创建的图片元素插入到 div 的最前面。不过,appendChild 方法会…...
Elasticsearch Serverless中的数据流自动分片深度解析
Elasticsearch Serverless中的数据流自动分片深度解析 一、Elasticsearch Serverless概述 1. 什么是Elasticsearch Serverless Elasticsearch Serverless是一种云端全托管的Elasticsearch服务,它基于云原生Serverless技术架构,提供自动弹性和完全免运…...
2025考研江南大学复试科目控制综合(初试807自动控制原理)
2025年全国硕士研究生招生考试江南大学考点 一年年的考研如期而至,我也变成了研二了,作为2次考研经历的学长,总是情不自禁地回想起自己的考研经历,我也会经常从那段经历中汲取力量。我能理解大多数考生考完后的的迷茫无助&…...
Elasticsearch分片数量是什么意思?
Elasticsearch中的分片(Shard)数量是一个重要概念,以下为你详细介绍它的含义及相关要点: ### 定义 分片是Elasticsearch将索引数据进行拆分的基本单元。简单来说,Elasticsearch会把一个索引的数据分割成多个较小的部分…...
PWN的知识之栈溢出
栈溢出 什么是栈溢出? 栈溢出(Stack Overflow)是指在程序运行过程中,向栈中存放的数据量超过了栈的最大容量,从而导致程序出现异常行为的情况。可以比作一个箱子原本只能容纳一定数量的物品,如果强行往里…...
java.lang.Error: FFmpegKit failed to start on brand:
如果你使用FFmpegKit的时候遇到了这个问题: java.lang.Error: FFmpegKit failed to start on brand: Xiaomi, model: MI 8, device: dipper, api level: 29, abis: arm64-v8a armeabi-v7a armeabi, 32bit abis: armeabi-v7a armeabi, 64bit abis: arm64-v8a.at c…...
TCPDump参数详解及示例
TCPDump参数详解及示例 TCPDump参数详解TCPDump -G的示例TCPDump -i any -s 2048 -G 600 -p udp -Z root -n -X -tt -w %Y_%m%d_%H%M_%S.pcap &的含义TCPDump是一款强大的网络数据包截获分析工具,可以将网络中传送的数据包的完全截获下来提供分析。它支持针对网络层、协议…...
Spring如何实现管理事务
目录 简介: 分类: 1.编程式事务管理: 2. 声明式事务管理: 3.事务传播和隔离级别: 配置 Spring 事务管理: 总结: 简介: Spring 通过事务管理器(Transaction Manager…...
windows C#-接口中的索引器
可以在接口上声明索引器。 接口索引器的访问器与类索引器的访问器有所不同,差异如下: 接口访问器不使用修饰符。接口访问器通常没有正文。 访问器的用途是指示索引器为读写、只读还是只写。 可以为接口中定义的索引器提供实现,但这种情况非…...
Launcher3主页面加载显示流程分析
布局结构 抓取布局后,可以看到每个图标是一个DoubleShadowBubbleTextView,父布局是CellLayout、workspace。 我们可以在CellLayout添加子view打印出调用堆栈信息,可以整体上看页面加载显示流程。 主要类 Launcher.java:主界面&…...
【读书笔记·VLSI电路设计方法解密】问题36:一个好的设计流程有哪些特点
由于IC实现与不断演进的技术节点密切相关,且各种新问题迅速涌现,一个优秀的设计流程必须具备灵活性,以应对这些新挑战,而无需进行大规模调整。 与此同时,为了克服当今SoC实现领域中出现的众多问题,整个EDA行业正在高速运转。新工具正在加速涌现;因此,一个优秀的设计流…...
C语言----共用体、枚举
目录 编辑 共用体 1. 定义 2. 格式 注意: 枚举 1. 定义: 2. 格式: 3. 说明: 面试题:枚举和宏定义区别? 共用体 1. 定义 不同数据类型的数据可以使用共同的存储区域,这种数据构造类…...
26.Java Lock 接口(synchronized 关键字回顾、可重入锁快速入门、Lock 对比 synchronized)
一、synchronized 关键字 1、synchronized 关键字回顾 synchronized 是 Java 中的关键字,是一种同步锁,它修饰的对象有以下几种 修饰一个类:其作用的范围是 synchronized 后面括号括起来的部分,作用的对象是这个类的所有对象 修…...
机器学习 学习知识点
机器学习 学习知识点 什么是消融实验(Ablation experiment)?num_step与batch_size的区别python glob.glob()函数认识python的条件判断之is not、is not None、is Nonetqdm介绍及常用方法softmax 激活函数。type_as(tesnor)Python OpenCV cv2.…...
GESP真题 | 2024年12月1级-编程题4《美丽数字》及答案(C++版)
描述 小杨有 n 个正整数,他认为一个正整数是美丽数字当且仅当该正整数是 9 的倍数但不是 8 的倍数。 小杨想请你编写一个程序计算个正整数中美丽数字的数量。 输入描述 第一行包含一个正整数 n,代表正整数个数 。 第二行包含 n 个正整数 a1, a2, a3…...
java并发之AQS
一、简介 AQS,全称:AbstractQueuedSynchronizer,是一个JDK提供的用于构建锁、同步器等线程协作工具类的框架,内部维护FIFO双向队列(双向链表实现)。 AQS重要属性: // 表示同步状态。它既可以表…...
4 种修复 IPhone 备份输入密码解锁的方法
您是否在 iTunes 中遇到过这样的消息:“输入密码以解锁您的 iPhone 备份”?出现这种情况是因为备份具有加密备份。当您通过 iTunes 为 iPhone 创建此备份时,您需要生成 iTunes 备份密码来保护和加密您的 iPhone 备份。当您想要更改 iPhone 备…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...
嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)
目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 编辑编辑 UDP的特征 socke函数 bind函数 recvfrom函数(接收函数) sendto函数(发送函数) 五、网络编程之 UDP 用…...
【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...
GeoServer发布PostgreSQL图层后WFS查询无主键字段
在使用 GeoServer(版本 2.22.2) 发布 PostgreSQL(PostGIS)中的表为地图服务时,常常会遇到一个小问题: WFS 查询中,主键字段(如 id)莫名其妙地消失了! 即使你在…...
