Maven 高级之分模块设计与继承、聚合

news/2024/12/22 11:10:59/

在软件开发中,随着项目规模的扩大,代码量和复杂度不断增加,传统的一体化开发模式逐渐暴露出诸多问题。为了解决这些问题,模块化开发应运而生,而 Maven 正是模块化开发的利器,它提供的继承和聚合机制为构建和管理多模块项目提供了强大的支持。本文将介绍其原理与实现!

其它教程:

maven 入门详解

一、传统开发模式

未分模块示例:所有的模块都放在一个目录之下

在不使用模块化管理的项目中,所有的代码都放在同一个项目目录下,这会导致一系列问题:

  1. 编译速度慢: 即使只修改了一行代码,也需要编译整个项目,随着项目规模的增大,编译时间会越来越长,严重影响开发效率。

  2. 代码耦合度高: 不同功能模块的代码交织在一起,修改一处代码可能会影响其他模块,导致代码难以维护和调试。

  3. 项目结构混乱: 缺乏清晰的模块划分,代码文件杂乱无章,难以理解和定位问题。

  4. 团队协作困难: 多个开发者同时修改同一个项目的代码,容易发生冲突,代码合并也变得更加复杂。

  5. 代码复用性低: 不同项目中可能存在重复的代码逻辑,但由于代码耦合在一起,难以提取和复用。

二、模块化开发

模块化开发的核心思想是将一个大型项目拆分成多个独立的模块,每个模块负责特定的功能,模块之间通过接口进行交互。

分模块示例:将整体的模块进行拆分

模块化开发的优势:

  1. 提高编译速度: 每个模块可以独立编译,修改一个模块的代码只需要重新编译该模块,大大缩短编译时间。

  2. 降低代码耦合度: 模块之间通过明确定义的接口进行交互,减少了模块之间的依赖性,提高了代码的可维护性和可测试性。

  3. 清晰的项目结构: 模块化的项目结构更加清晰,易于理解和管理,方便开发者快速定位和修改代码。

  4. 提高团队协作效率: 不同团队可以负责不同的模块,并行开发,互不干扰,提高开发效率。

  5. 提高代码复用性: 独立的模块可以方便地在其他项目中复用,避免重复造轮子。

三、Maven:模块化开发的强大工具

那么我们已经把模块已经划分好了,那么这些模块直接繁琐的依赖管理如何处理呢?

这个时候,Maven 为我们提供了强大的继承和聚合机制,完美支持模块化开发。

1. Maven 继承:抽取公共配置,避免冗余
  • 概念:继承描述的是两个工程间的关系,与java中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承。

  • 作用:简化依赖配置、统一管理依赖

原理: 子模块继承父模块的配置,例如依赖管理、插件配置、版本号等。这避免了在每个子模块中重复定义相同的配置,简化了 pom.xml 文件,并确保了项目配置的一致性。并且maven还支持多重继承。

示例:

示例实现:

  • 父模块 (parent-module) 的 pom.xml:

<project><groupId>com.example</groupId><artifactId>parent-module</artifactId><version>1.0.0</version><packaging>pom</packaging> <!-- 打包方式为 pom --><properties><java.version>17</java.version><spring.version>3.0.2</spring.version></properties><dependencyManagement>  <!-- 声明依赖,但不引入 --><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.10.1</version><configuration><source>${java.version}</source><target>${java.version}</target></configuration></plugin></plugins></build>
</project>

  • 子模块 (user-module) 的 pom.xml:

<project><parent><groupId>com.example</groupId><artifactId>parent-module</artifactId><version>1.0.0</version><relativePath>../parent-module/pom.xml</relativePath> <!--  相对路径指向父模块的pom.xml  --></parent><artifactId>user-module</artifactId><packaging>jar</packaging> <!-- 打包方式为 jar --><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId>  <!--  无需指定版本号,从父模块继承 --></dependency></dependencies>
</project>

其余子模块省略.......

2. Maven 聚合:统一构建,简化操作

那此时,大家试想一下,如果开发一个大型项目,拆分的模块很多,模块之间的依赖关系错综复杂,那此时要进行项目的打包、安装操作,是非常繁琐的。 不过通过maven的聚合就可以轻松实现项目的一键构建(清理、编译、测试、打包、安装等)。

  • 聚合:将多个模块组织成一个整体,同时进行项目的构建。

  • 聚合工程:一个不具有业务功能的“空”工程(有且仅有一个pom文件) 【PS:一般来说,继承关系中的父工程与聚合关系中的聚合工程是同一个】

  • 作用:快速构建项目(无需根据依赖关系手动构建,直接在聚合工程上构建即可)

原理: 父模块将多个子模块聚合在一起,通过父模块可以一次性构建所有子模块,简化了构建过程。

实现: 在父模块的 pom.xml 文件中使用 <modules> 标签声明要聚合的子模块。

  • 父模块 (parent-module) 的 pom.xml:

<project><!-- ... (其他配置与继承示例相同) ... --><modules><module>user-module</module><module>product-module</module><module>order-module</module></modules></project>

构建过程: 在父模块目录下执行 mvn clean install 命令,Maven 会自动构建所有子模块。

依赖关系: 子模块之间可以通过声明依赖来相互引用。 例如,order-module 依赖于 user-module 和 product-module:

<project><!-- ... --><artifactId>order-module</artifactId><!-- ... --><dependencies><dependency><groupId>com.example</groupId><artifactId>user-module</artifactId><version>1.0.0</version></dependency><dependency><groupId>com.example</groupId><artifactId>product-module</artifactId><version>1.0.0</version></dependency></dependencies>
</project>

3 继承与聚合对比
  • 作用

    • 聚合用于快速构建项目

    • 继承用于简化依赖配置、统一管理依赖

  • 相同点:

    • 聚合与继承的pom.xml文件打包方式均为pom,通常将两种关系制作到同一个pom文件中

    • 聚合与继承均属于设计型模块,并无实际的模块内容

  • 不同点:

    • 聚合是在聚合工程中配置关系,聚合可以感知到参与聚合的模块有哪些

    • 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己

总结:

Maven 的继承和聚合机制为模块化开发提供了强大的支持,通过合理地划分模块,并利用 Maven 的特性,可以构建出结构清晰、易于维护、扩展性强的应用程序。 理解并熟练运用 Maven 的高级特性,是每个 Java 开发者必备的技能。感谢各位看官的观看,下期见,谢谢~


http://www.ppmy.cn/news/1537494.html

相关文章

产品经理内容分享(二):AI产品经理的入门路线图

引言 想象这样一个场景&#xff1a;早晨的阳光穿透窗帘&#xff0c;投射在新一代智能机器人上&#xff0c;它正静静等待着你的第一个命令开始全新的一天。这样的场景听起来像是科幻小说里的情节&#xff0c;但实际上&#xff0c;这正是AI产品经理们工作的成果。如果你对这样的…

如何从U盘恢复已删除的文件

丢失重要文件可能是一场噩梦&#xff0c;感觉就像你内心死了一样。但是&#xff0c;你在 U 盘中备份了重要数据&#xff0c;因此你不会担心丢失数据。现在&#xff0c;猜猜怎么了&#xff1f;你也丢失了 U 盘中的文件。它可能被错误删除&#xff0c;或者你在没有检查的情况下格…

PyQt入门指南八 多线程编程入门

在PyQt应用程序中&#xff0c;多线程编程是非常重要的&#xff0c;因为它可以防止GUI界面在执行耗时操作时冻结。Python的threading模块和PyQt的QThread类都可以用来实现多线程&#xff0c;但在PyQt中&#xff0c;推荐使用QThread&#xff0c;因为它更好地与Qt的事件循环集成。…

LLM prompt提示设计与优化

参看&#xff1a; https://help.aliyun.com/zh/model-studio/use-cases/prompt-engineering-guide?spma2c4g.11186623.0.0.136d55ceDnHbPK https://tenten.co/learning/co-star-tidd-ec-prompt-framework/ 大语言模型中 Prompt 的设计和优化方法&#xff0c;包括使用 Prompt 框…

【电路笔记】-求和运算放大器

求和运算放大器 文章目录 求和运算放大器1、概述2、反相求和放大器3、同相求和放大器4、减法放大器5、应用5.1 音频混合器5.2 数模转换器 (DAC)6、总结1、概述 在我们之前有关运算放大器的大部分文章中,仅将一个输入应用于反相或非反相运算放大器的输入。在本文中,将讨论一种…

第一个Flutter应用解析(一)

1、创建项目 1.1 新建 1.2 选择Flutter SDK的位置 1.3 项目名称 英文单词加下划线起名规范&#xff0c;其他默认即可。 1.4 点击运行 发生报错显示我们的JAVA版本不符合 1.5 更改版本设置 1.6 再次启动项目 2、分析页面代码 以下是lib/main.dart的源代码&#xff08;为了阅…

Python 如何使用 multiprocessing 模块创建进程池

Python 如何使用 multiprocessing 模块创建进程池 一、简介 在现代计算中&#xff0c;提升程序性能的一个关键方法是并行处理&#xff0c;尤其是当处理大量数据或计算密集型任务时&#xff0c;单线程可能不够高效。Python 提供了多个模块来支持并行计算&#xff0c;其中最常用…

服装生产管理的智能化:SpringBoot框架

3 系统分析 3.1 可行性分析 可行性分析是该平台系统进行投入开发的基础第一步&#xff0c;必须对其进行可行性分析才能够降低不必要的需要从而使资源合理利用&#xff0c;更具有性价比和降低成本&#xff0c;同时也是系统平台的成功的未雨绸缪的一步。 3.1.1 技术可行性 技术…