【Maven】多module项目优雅的实现pom依赖管理
【Maven】多module项目优雅的实现pom依赖管理
- 【一】方案设计原则
- 【二】项目结构示例
- 【三】实现思路
- 【1】可能的问题点:
- 【2】解决方案的思路:
- 【3】需要注意的地方:
- 【4】可能的错误:
- 【四】实现案例
- 【1】父POM设计(parent-project/pom.xml)
- 【2】子模块示例(common-core/pom.xml)
- 【3】模块间依赖(service-module/pom.xml)
- 【五】总结
【一】方案设计原则
(1)统一依赖版本管理
所有依赖版本在父POM中集中定义,子模块无需指定版本号。
(2)模块职责分离
按功能划分模块(如核心工具、数据访问、API接口等),减少耦合。
(3)依赖继承与复用
公共依赖由父模块管理,模块间通过引入所需依赖。
(4)BOM集成
使用Spring Boot和第三方库的BOM(Bill of Materials)统一管理版本。
(5)插件集中配置
在父POM中统一配置编译、打包等插件,确保构建一致性。
【二】项目结构示例
parent-project(根项目)
├── pom.xml # 父POM
├── common-core # 通用工具模块
│ └── pom.xml
├── common-dao # 数据访问模块
│ └── pom.xml
├── api-module # API接口模块
│ └── pom.xml
└── service-module # 业务逻辑模块
└── pom.xml
【三】实现思路
通常,一个多模块项目有一个父pom,然后各个子模块继承这个父pom。父pom负责管理公共的依赖版本、插件配置等。子模块可以声明自己的依赖,而版本号由父pom统一管理。这样可以避免版本冲突,也方便统一升级。
优雅管理可能包括:依赖版本统一管理、依赖分类(比如核心依赖、工具类依赖)、避免重复声明、处理模块之间的依赖关系等。
【1】可能的问题点:
(1)父pom如何管理所有依赖的版本?
(2)如何将依赖按功能分组,比如分成dependencies和dependencyManagement?
(3)如何处理不同模块间的依赖共享?
(4)如何避免子模块中重复声明版本号?
(5)如何管理插件的版本和配置?
【2】解决方案的思路:
(1)使用父pom的dependencyManagement来统一管理所有依赖的版本,子模块引入依赖时不需要指定版本。
(2)将常用依赖组合成bom(Bill of Materials),或者使用Spring Boot已有的BOM,比如spring-boot-dependencies。
(3)将项目分为多个模块,比如核心模块、通用工具模块、API模块、服务模块等,每个模块负责特定的功能,减少重复依赖。
(4)在父pom中定义公共的插件管理,确保所有子模块使用相同的插件版本和配置。
(5)使用模块化的依赖管理,比如将数据库相关依赖、Web相关依赖分别管理,方便按需引入。
【3】需要注意的地方:
(1)父pom中的依赖管理部分应该清晰,按功能或类别分组,方便查找和维护。
(2)子模块只声明需要的依赖,不重复版本。
(3)避免循环依赖,尤其是在模块之间的依赖关系上。
(4)使用import来引入其他BOM,特别是当项目需要整合多个BOM时,比如同时使用Spring Boot和Spring Cloud的BOM。
【4】可能的错误:
(1)在子模块中错误地指定了版本号,导致父pom的版本管理失效。
(2)模块之间的依赖关系没有正确声明,导致编译或运行时缺少必要的依赖。
(3)没有正确管理插件的版本,导致构建不一致。
(4)父pom中漏掉了某些公共依赖的管理,导致子模块需要自行管理版本,引发冲突。
【四】实现案例
【1】父POM设计(parent-project/pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>1.0.0-SNAPSHOT</version><packaging>pom</packaging><!-- 模块声明 --><modules><module>common-core</module><module>common-dao</module><module>api-module</module><module>service-module</module></modules><!-- 继承Spring Boot父POM --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.5</version><relativePath/> <!-- 从仓库查找 --></parent><!-- 依赖管理:统一版本 --><dependencyManagement><dependencies><!-- 集成Spring Cloud BOM(可选) --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>2022.0.4</version><type>pom</type><scope>import</scope></dependency><!-- 自定义依赖版本 --><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>32.1.2-jre</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.28</version><scope>provided</scope></dependency></dependencies></dependencyManagement><!-- 公共依赖(所有子模块继承) --><dependencies><!-- Spring Boot Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- Lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency></dependencies><!-- 插件管理 --><build><pluginManagement><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>17</source><target>17</target></configuration></plugin></plugins></pluginManagement></build>
</project>
【2】子模块示例(common-core/pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project><modelVersion>4.0.0</modelVersion><parent><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>1.0.0-SNAPSHOT</version></parent><artifactId>common-core</artifactId><!-- 声明模块特有依赖 --><dependencies><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId> <!-- 版本由父POM管理 --></dependency></dependencies>
</project>
【3】模块间依赖(service-module/pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project><modelVersion>4.0.0</modelVersion><parent><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>1.0.0-SNAPSHOT</version></parent><artifactId>service-module</artifactId><dependencies><!-- 依赖其他模块 --><dependency><groupId>com.example</groupId><artifactId>common-core</artifactId><version>${project.version}</version></dependency><dependency><groupId>com.example</groupId><artifactId>common-dao</artifactId><version>${project.version}</version></dependency><!-- Spring Boot Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
</project>
【五】总结
(1)分层管理依赖
父POM:管理全局依赖版本、插件和公共配置。
子模块:仅声明自身需要的依赖,不重复定义版本。
(2)活用BOM
通过导入Spring Boot、Spring Cloud或其他第三方BOM,简化版本协调。
(3)模块化设计
每个模块职责单一,通过依赖传递共享通用组件。
(4)版本变量提取
对频繁变更的版本号,可在父POM中定义集中管理。
(5)持续梳理依赖
定期使用mvn dependency:tree分析依赖树,避免冗余和冲突。
相关文章:
【Maven】多module项目优雅的实现pom依赖管理
【Maven】多module项目优雅的实现pom依赖管理 【一】方案设计原则【二】项目结构示例【三】实现思路【1】可能的问题点:【2】解决方案的思路:【3】需要注意的地方:【4】可能的错误: 【四】实现案例【1】父POM设计(pare…...
前端vue引入特殊字体不生效
引入特殊字体ttf,TTF等发现开发环境中生效,项目部署后不生效何解? 1. 本地生效的原因 本地使用的是本地的资源,控制台可以看到对ttf文件的请求与加载。 2.部署后不生效的原因与解决 控制台可以看到对ttf资源文件的请求加载失败…...
【Linux】--- 基础开发工具之yum/apt、vim、gcc/g++的使用
Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏: Linux网络编程 本篇博客我们来认识一下Linux中的一些基础开发工具 --- yum,vim,gcc/g。 🏠 yum 🎸 什么是yum 当用户想下载软…...
WEB安全--SQL注入--INTO OUTFILE
一、INTO OUTFILE 函数语法: SELECT column1, column2, INTO OUTFILE file_path FROM your_table WHERE your_conditions; 使用此方式在SQL注入的过程中可以: 1、上传shell得到数据库的后端的操作权限 2、爆出数据库的信息 二、使用该函数的条件&#…...
如何从0开始将vscode源码编译、运行、打包桌面APP
** 网上关于此的内容很少,今天第二次的完整运行了,按照下文的顺序走不会出什么问题。最重要的就是环境的安装,否则极其容易报错,请参考我的依赖版本以及文末附上的vscode官方指南 ** 第一步:克隆 VSCode 源码 首先…...
关于视频去水印的一点尝试
一. 视频去水印的几种方法 1. 使用ffmpeg delogo滤镜 delogo 滤镜的原理是通过插值算法,用水印周围的像素填充水印的位置。 示例: ffmpeg -i input.mp4 -filter_complex "[0:v]delogox420:y920:w1070:h60" output.mp4 该命令表示通过滤镜…...
如何在 Java 应用中实现数据库的主从复制(读写分离)?请简要描述架构和关键代码实现?
在Java应用中实现数据库主从复制(读写分离) 一、架构描述 (一)整体架构 主库(Master) 负责处理所有的写操作(INSERT、UPDATE、DELETE等)。它是数据的源头,所有的数据变…...
【css】width:100%;padding:20px;造成超出100%宽度的解决办法 - box-sizing的使用方法 - CSS布局
问题 修改效果 解决方法 .xx {width: 100%;padding: 0 20px;box-sizing: border-box; } 默认box-sizing: content-box下, width 内容的宽度 height 内容的高度 宽度和高度的计算值都不包含内容的边框(border)和内边距(padding&…...
【TI C2000】F28002x的系统延时、GPIO配置及SCI(UART)串口发送、接收
【TI C2000】F28002x的系统延时、GPIO配置及SCI(UART)串口发送、接收 文章目录 系统延时GPIO配置GPIO输出SCI配置SCI发送、接收测试附录:F28002x开发板上手、环境配置、烧录及TMS320F280025C模板工程建立F28002x叙述烧录SDK库文件说明工程建…...
【PyQt】信号与槽机制
PyQt信号与槽机制详解 🚀 一、信号与槽类型 🔌 1. 内置信号 📡 # 按钮点击信号 🖱️ QPushButton.clicked# 文本输入变化信号 ⌨️ QLineEdit.textChanged# 窗口关闭信号 🚪 QWidget.closeEvent2. 自定义信号 ✨ c…...
STM32 是什么?同类产品有哪些
STM32 是什么? STM32 是由意法半导体(STMicroelectronics)推出的基于 ARM Cortex-M 内核 的 32 位微控制器(MCU)系列。它专为高性能、低功耗的嵌入式应用设计,广泛应用于以下领域: 工业控制&am…...
20250213编译飞凌的OK3588-C_Linux5.10.209+Qt5.15.10_用户资料_R1
20250213编译飞凌的OK3588-C_Linux5.10.209Qt5.15.10_用户资料_R1 2025/2/13 11:43 缘起:飞凌发布了高版本内核的适配OK3588-C的Buildroot的SDK:OK3588-C_Linux5.10.209Qt5.15.10_用户资料_R1。 但是编译异常了。 于是按照百度升级libc6,可以…...
【DeepSeek】DeepSeek R1 本地windows部署(Ollama+Docker+OpenWebUI)
1、背景: 2025年1月,DeepSeek 正式发布 DeepSeek-R1 推理大模型。DeepSeek-R1 因其成本价格低廉,性能卓越,在 AI 行业引起了广泛关注。DeepSeek 提供了多种使用方式,满足不同用户的需求和场景。本地部署在数据安全、性…...
AI知识库 - Cherry Studio
1 引言: 最近 DeepSeek 很火啊,想必大家都知道,DeepSeek 这个开源的模型出来后,因其高质量能力和R1 的思维链引发了大家本地部署的热潮。我也不例外,本地部署了一个 14B 的模型,然后把,感觉傻傻…...
【ubuntu24.04】 强制重启导致大模型的磁盘挂载出错
挂载NTFS文件系统出错 各种模型放在了这个机械硬盘上,虽然速度慢,但是好在容量大。大模型在工作,但是程序看起来有问题,导致系统卡死了,然后我重启了,然后报错:wrong fs type bad option &…...
OpenLayer创建第一个基础地图实例
OpenLayers创建第一个基础地图实例 OpenLayers 是一个开源的 JavaScript 库,用于在网页上显示交互式地图。它支持多种地图源,包括 OpenStreetMap、Google Maps、Bing Maps 等。本文将介绍如何使用 OpenLayers 创建一个基础地图实例。 1. 准备工作 在开…...
Git命令摘录
使用 Git 升级软件通常是指通过 Git 仓库获取软件的最新版本或更新代码。以下是详细的步骤和方法: 1. 克隆软件仓库 如果这是你第一次获取软件代码,可以使用 git clone 命令将远程仓库克隆到本地。 git clone <仓库地址> 例如: git cl…...
windows 通过docker 安装mysql
参考:Docker安装并使用Mysql(可用详细)_docker 安装mysql-CSDN博客 1. 拉取镜像:docker pull mysql:5.7 2. 查看镜像:docker image 3. 创建mysql 容器实例,并将data 目录挂载到本地d盘上 docker run --n…...
实现Tree 树形控件的鼠标拖拽功能
1.element中的el-tree实现可拖拽节点 通过 draggable 属性可让节点变为可拖拽 <el-tree :data"data" node-key"id" default-expand-all node-drag-start"handleDragStart" node-drag-enter"handleDragEnter" node-drag-leave"…...
同为科技智能PDU助力Deepseek人工智能和数据交互的快速发展
1 2025开年,人工智能领域迎来了一场前所未有的变革。Deepseek成为代表“东方力量”的开年王炸,不仅在国内掀起了技术热潮,并且在全球范围内引起了高度关注。Deepseek以颠覆性技术突破和现象级应用场景席卷全球,这不仅重塑了产业格…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
