如何使用Maven模块化管理的继承和聚合机制

news/2025/2/23 20:12:21/文章来源:https://www.cnblogs.com/nuccch/p/18732728

在说明如何使用Maven模块化管理的继承和聚合机制之前,需要先澄清一些概念性的东西:
1.Maven是什么?
2.什么是Maven模块化管理?
3.Maven模块化管理的继承和聚合机制是什么含义?

Maven是什么

Maven是Java项目开发中使用的一种依赖包管理工具,与其功能相似的还有另外一个叫做Gradle的工具。在没有Maven之前,Java项目的依赖包管理是需要将jar包拷贝到项目源码中的,在依赖包多的情况下,将会使得项目源码非常庞大,也不利于团队协作。使用Maven或者Gradle可以将项目依赖声明在一个指定的配置文件中,这样就无需手动将依赖jar包拷贝到项目源码中了,一方面项目源码不再无限增大,另一方面能起到一次声明到处构建的效果,这样大大提高了团队协作的效率。
依赖包管理是Maven最核心最基础的功能,除此之外,还能使用Maven实现项目构建和打包,通过插件化的机制实现代码检查,单元测试等等,功能非常强大。

什么是Maven模块化管理

在项目开发过程中,常常有这种需求:将一些通用的工具类方法提取出来,方便在多个地方调用。但是仅仅这样做只能在一个项目中使用,当需要在多个项目中使用这些通用的工具方法时,就不得不将这些工具类方法再重复定义一次。这样既产生了编码重复,也为方法的管理带来了新的挑战(如:如何统一升级方法实现等)。为了实现在多个Java项目中共用一些通用的工具类方法,Maven提供了一种模块化的机制,可以将这些通用的工具类方法放到一个模块中,然后将这个模块打包为独立的jar包,在其他项目中引用这个公共的jar包即可。

Maven模块化管理的继承和聚合机制是什么含义

所谓继承,就是可以在一个“父模块”中统一声明依赖信息,以及一些其他参数,这样在子模块中就可以直接引用即可,实现了在相同的“父模块”中实现统一的依赖版本管理,便于依赖jar包的版本冲突解决。
所谓聚合,就是提供了一种机制可以实现多个Maven模块的统一构建,模块间的依赖更新等问题,用于提升开发效率。

虽然继承和聚合是两个独立的概念,但是他们也有一些共同点:
1.聚合与继承的实现都需要有一个父模块,父模块打包方式均为pom
2.聚合与继承均属于设计型模块,并无实际的模块内容

如何使用Maven模块化管理的继承和聚合机制

父模块设置

上述已经讲过,Maven工具的继承和聚合机制都需要一个父模块,且父模块的打包方式必须为pom,配置示例如下:

<groupId>xxx.yyy</groupId>
<artifactId>xxxParent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<!-- 设置打包方式为 pom -->
<packaging>pom</packaging>

继承机制

Maven继承机制主要解决的是依赖管理,实践如下:

第一步,在父模块中通过dependencyManagement标签声明需要依赖的jar包以及版本。

<dependencyManagement><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.2.10.RELEASE</version><scope>test</scope></dependency></dependencies>
</dependencyManagement>

除了可以在父模块中声明需要依赖的jar包及版本外,还可以通过pluginManagement声明构建时需要的插件及版本:

<build><pluginManagement><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.0</version></plugin></pluginManagement>
</build>

还可以在父模块中实现发布管理,用于配置Maven私服仓库信息:

<distributionManagement><repository><id>private-release</id><url>http://192.168.10.100:9015/repository/private-release/</url></repository><snapshotRepository><id>private-snapshot</id><url>http://192.168.10.100:9015/repository/private-snapshot/</url></snapshotRepository>
</distributionManagement>

私服信息一旦在父模块中声明了,就会全局生效,无需在子模块中再次声明。

第二步,在子模块中声明父模块,并直接引入需要的依赖jar包即可,无需再指定版本。

<!-- <groupId>xxx.yyy</groupId> -->
<artifactId>zzzSubModel</artifactId>
<version>1.0-SNAPSHOT</version><parent><!-- 父模块的坐标与版本 --><groupId>xxx.yyy</groupId><artifactId>xxxParent</artifactId><version>1.0.0-SNAPSHOT</version><!-- 父模块的相对路径 --><relativePath>../pom.xml</relativePath>
</parent>
<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId></dependency>
</dependencies>

在子模块中直接引用已经在父模块中声明的构建插件,无需再声明插件版本:

<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-deploy-plugin</artifactId></plugin></plugins>
</build>

在子模块中声明父模块时对relativePath属性的设置说明:
1.relativePath属性可以省略,前提是父模块已经install到本地仓库或deploy到私服,否则子模块无法定位到父模块,不能通过编译
2.相对路径最后可以不写pom.xml,只定位到父模块的文件夹也可以

聚合机制

继承机制很好地解决了在同一个项目中存在多个模块时的版本依赖管理,但是当多个模块之间存在依赖时,为了方便处理模块之间的依赖更新问题,或者说为了方便在执行Maven构建命令时对所有模块统一进行构建,这时候就需要使用到Maven的聚合机制了。
使用Maven的聚合机制非常简单,只需要在父模块中声明模块信息即可,配置如下:

<modules><module>xxx-yyy-core</module><module>xxx-xxx-model</module><module>xxx-xxx-app</module>
</modules>

在同时使用Maven继承和聚合机制时可能会遇到如下问题:

前面说在子模块中声明父模块时relativePath属性可以省略,前提是父模块已经构建并install到本地仓库或deploy到私服,否则子模块无法构建,但此时父模块同时也聚合了子模块,要构建父模块就又要一起构建子模块,但构建子模块又需要父模块已经构建并install到本地仓库或deploy到私服......陷入了套娃问题。
此时构建父模块会报错: Non-resolvable parent POM for XXX.XXX.XXX Could not find artifact com.mzz:parent-maven:pom:1.0-SNAPSHOT and ‘parent.relativePath’ points at wrong local POM,原因是无法定位父模块。

解决方法也很简单,要么老老实实在子模块中parent标签中加入relativePath属性,使Maven可以根据相对路径找到父模块;要么,先将父模块中的modules注释掉,暂时不做聚合,将父模块installdeploy之后再取消注释,然后就能一起构建了。

关于父模块版本的设置

值得注意的是:在子模块中声明父模块时,父模块的的<version>属性不能直接使用变量。父模块的版本号必须是硬编码的,不能通过变量来动态设置。这是因为父模块的版本号在子模块中引用时,需要是一个固定的值,以便Maven能够正确解析和构建项目。

【参考】
maven 父模块不包含子模块 maven子模块版本继承
Maven高级-详解Maven的继承与聚合
Maven中 <parent > 的<version>可以使用变量吗

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/888542.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用MyBatis框架时Mapper传参是否需要使用@Param注解

在使用MyBatis作为Java项目的ORM框架时,在Mapper接口中传递参数需要通过@Param注解指定参数名称,这样才能在Mapper接口对应的xml文件中引用到对应名称的参数。如果不在Mapper接口中明确使用@Param注解时将会报错:找不到指定名称的参数。 追根溯源,这要从MyBatis获取Mapper接…

关于在阿里云服务器上搭建简单的keepalived主备服务器时出现的问题

问题:在进行keepalived主备服务器配置时,仅配置了RID,状态,通讯端口,VRID,优先级,通告报文发送时间,密码认证部分,VIP。在启动服务时,发现两台设备均跳转状态为MASTER。原因:出现这问题的场景是在阿里VPS云服务器网络环境中,因为路由交换层禁用了ARP的广播限制,造…

子串分值

‌输入和初始化‌: 读取字符串 str,并从索引 1 开始存储(C++ 中字符串索引从 0 开始,但这里为了简化计算,从 1 开始)。 n 存储字符串的长度。 数组 l[i] 存储字符 str[i] 上一次出现的位置。 数组 r[i] 存储字符 str[i] 下一次出现的位置。 数组 p 用于临时存储每个字符最…

【专题】2024年新能源汽车市场年度竞争报告汇总PDF洞察(附原数据表)

原文链接: https://tecdat.cn/?p=39740 在当下快速变革的时代,新能源汽车市场正处于关键的发展十字路口。过去几年间,市场经历了一系列深刻的结构性调整,从市场份额的重新分配到消费者行为模式的显著转变,每一个变化都蕴含着巨大的市场信号。深入分析这些变化背后的数据逻…

pikachu靶场搭建教程

详细介绍了pikachu靶场的搭建,并且附有安装包需要的东西phpStudy: 链接: https://pan.baidu.com/s/1fJ-5TNtdDZGUf5FhTm245g 提取码:0278 pikachu-master: Github链接:Github 链接 链接: https://pan.baidu.com/s/1lDdlxNaa3YjhIEj-WWB3qw 提取码:0278打开 phpstudy ,…

2.17周报

一、本周内容总结本周主要进行了蓝桥和天梯的训练,训练了3场蓝桥、2场天梯,剩余时间的就是赛后补题 补题的过程也重新理清了很多知识,包括gcd和lcm的应用,多项式除法的过程等等 对于蓝桥和天梯的赛制,还重新背了下很多算法的板子,包括求最短路的多种方法,不同范围求组合…

来点树链剖分

树链剖分树链剖分学习笔记 引入 给你一棵树,先单点加,再路径求和,你觉得很简单,用树上差分解决了这个问题。 再给你一棵树,先路径加,再单点查询,你觉得很简单,用树上差分解决了这个问题。 又给你一棵树,上述操作都有,而且顺序不分先后,你发现树上差分不能解决这个问…

《轻松上手:LangChain 的安装与验证全流程》

在当今快速发展的技术领域,掌握新工具是提升工作效率的关键。今天,我将为大家详细介绍如何轻松安装 LangChain,并验证其是否成功安装,让你迅速开启探索这一强大工具的旅程。 首先,在命令行中运行以下命令来安装 LangChain: pip install langchain安装完成后,为了确保一切…

双向广搜 P1032 洛谷 [NOIP 2002 提高组] 字串变换

双向广搜 P1032 洛谷 [NOIP 2002 提高组] 字串变换 题目背景 本题不保证存在靠谱的多项式复杂度的做法。测试数据非常的水,各种做法都可以通过,不代表算法正确。因此本题题目和数据仅供参考。 本题为搜索题,本题不接受 hack 数据。关于此类题目的详细内容 题目描述 已知有两…

uniapp uview u-form表单校验:表单有值却校验不通过的问题

<u-form-item label="数量" required prop="num"><u-input v-model="form.num"></u-input> </u-form-item>检查校验不通过的字段值类型是什么,如果是非string类型,要在rules上指定值类型。原因:u-form的校验规则是值…

BUS设计中的DeadLock死锁问题

本文讨论一下 BUS 设计中的 DeadLock 死锁问题,或者叫做 Cyclic Dependency 循环依赖问题。其含义是指 A 的动作导致 B 的动作无法进行下去,同样 B 的动作导致 A 的动作无法进行下去,二者相互依赖,形成死锁。 1 AXI握手死锁 在学习 AXI 协议时,手册中提到了 AXI 握手死锁,…

字符串-str

字符串-str 1.1 特点需要加上引号,单引号与双引号都可以,包含了多行内容的时候还可以用三引号name = rock #报错,没有引号识别为变量名, name = "rock" print(name) name = kyle print(name) name = """rock #多行内容时使用三引号,区分三引…