Maven模块化最佳实践

news/2024/5/26 20:42:37/文章来源:https://blog.csdn.net/littleschemer/article/details/136555202

一,模块化的原因及意义

模块化是一种将大型的软件系统拆分成相互独立的模块的方法。具有以下优势:

  1. 代码复用:不同的模块可以共享相同的代码。这样可以避免重复编写相同的代码,提高开发效率。

  2. 模块独立性:每个模块都可以独立构建、测试和部署。这样可以降低整个项目的维护成本,例如当有一个模块需要更新时,只需要重新构建该模块而不会影响其他模块。

  3. 模块化开发:开发人员可以专注于某个特定的模块,而不需要关心整个项目的复杂性。这样可以提高开发效率和代码质量。

  4. 可扩展性:通过定义模块之间的依赖关系,可以方便地引入和管理第三方库和框架。这样可以提高项目的灵活性和可扩展性。

JDK从9版本开始,也对基础类库进行了模块化。

二,maven对模块化的支持

Maven是一个用于构建和管理Java项目的工具。它支持模块化开发,使开发人员能够将项目分解为多个独立的模块,并且可以独立地构建、测试和部署这些模块。

要使用Maven进行模块化开发,需要在项目的根目录下创建一个pom.xml文件,并在该文件中定义项目的基本信息和依赖关系。然后,在每个模块的目录中也需要创建一个pom.xml文件,并在该文件中定义模块的信息和依赖关系。

需要注意的是,子模块本身也可以作为其他模块的父模块。例如jforgame的子模块jforgame-socket-parent本身也有三个子模块。

三,模块化的继承效果

在Maven中,继承指的是使用父项目定义的配置信息来为子项目提供默认的配置。这种继承关系可以帮助开发者减少重复的配置,并确保子项目与父项目保持一致的构建方式。maven子模块可以继承的有以下内容

  • 配置
  • 依赖声明
  • 插件声明

3.1继承配置

在Maven中,继承属性是指子项目可以继承父项目中定义的属性值,也可以重新覆盖父项目的同名参数。

在实践中,我们可以把所有子模块需要的依赖版本,编译参数等配置统一放到父模块进行声明。这样,便于查阅与修改。例如jforgame-parent的pom配置

    <groupId>org.jforgame</groupId><artifactId>jforgame-parent</artifactId><version>${revision}</version><packaging>pom</packaging><name>jforgame-parent</name><properties><revision>1.0.0</revision><java.version>8</java.version><maven.compiler.source>${java.version}</maven.compiler.source><maven.compiler.target>${java.version}</maven.compiler.target><maven.compiler.compilerVersion>${java.version}</maven.compiler.compilerVersion><project.build.sourceEncoding>utf-8</project.build.sourceEncoding><jackson.version>2.12.1</jackson.version><juit.version>4.13.1</juit.version><dom4j.version>2.1.3</dom4j.version><mina.version>2.0.7</mina.version></properties>

3.2继承依赖

在Maven中,继承依赖是指子项目可以继承父项目中定义的依赖管理。这样可以简化子项目的依赖配置,避免重复定义和维护。

3.2.1管理所有子模块的依赖版本

父项目可以通过在<dependencyManagement>标签中定义的依赖,子模块可以继承而无需申明版本号。这样可以避免子模块之间引入不同版本号的依赖。这个功能特别是在引入springboot环境之后,就显得特别有用。

引入springboot有两种方式,一种是让模块继承springboot,例如GameKeeper的用法

	<groupId>org.jforgame</groupId><artifactId>gamekeeper</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>gamekeeper</name><description>游戏后台管理平台</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.1</version></parent>

另外一种就是将springboot的依赖以import的方式在父项目可以的<dependencyManagement>标签申明。如下所示(scope为import代表只申明依赖及其版本,不实际引入

 <dependencyManagement><dependencies><dependency><!-- Import dependency management from Spring Boot --><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${springboot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

3.2.2全局注入子模块的公有依赖

父模块可以把子模块都需要的依赖都统一进行申明,这样,子依赖即使没有显示引入,都会被动全部拥有,这样可以减少配置。典型的这些依赖有junit,sl4f等等。如jforgame项目的父模块申明

    <!-- 全局依赖,所有子模块均会导入--><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope></dependency><!-- 日志系统 --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId></dependency><dependency><groupId>log4j</groupId><artifactId>apache-log4j-extras</artifactId></dependency></dependencies>

综上所述,若需子模块自动拥有,则在父模块的<dependencies></dependencies>进行申明;所有子模块需要的依赖及其版本,在父模块的<dependencyManagement>标签进行申明。

3.3继承插件

在Maven中,除了继承依赖外,还可以通过继承插件来实现父子项目之间的插件配置共享和继承。这样可以避免在每个子项目中重复配置相同的插件。

maven同样提供了<pluginManagement>标签和<plugins>标签,至此全局管理子模块插件版本及统一插入。与依赖类似,这里不做重复演示。

四、模块化的聚合效果

在Maven中,聚合(aggregation)是一种将多个相关的项目组合在一起管理的方式。通过聚合,可以将多个项目作为一个整体来构建、测试和部署,简化了多项目管理的复杂度。

要实现项目的聚合,需要创建一个父项目(也称为聚合项目),并在父项目的pom.xml中声明子项目。父项目可以是一个普通的Maven项目,其packaging类型可以是pom,jar,war或其他类型。

例如jforgame的配置。在根目录下执行mvn package install命令的时候,会递归把所有子模块都打包安装到本地maven仓库,非常方便。

    <modules><module>hotswap</module><module>jforgame-commons</module><module>jforgame-orm</module><module>jforgame-demo</module><module>jforgame-codec-parent</module><module>jforgame-socket-parent</module></modules>

实践上,maven的继承和聚合是相辅相成的,一般都是整合起来用。 

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

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

相关文章

ElasticSearch学习篇10_Lucene数据存储之BKD动态磁盘树

前言 基础的数据结构如二叉树衍生的的平衡二叉搜索树通过左旋右旋调整树的平衡维护数据&#xff0c;靠着二分算法能满足一维度数据的logN时间复杂度的近似搜索。对于大规模多维度数据近似搜索&#xff0c;Lucene采用一种BKD结构&#xff0c;该结构能很好的空间利用率和性能。 …

IO学习--02

标准IO由ANSI C库说明&#xff0c;在很多系统都实现了标准IO库。标准IO库处理很多细节&#xff0c;如缓冲的分配、优化长度执行IO等&#xff0c;使得用户不需要考虑选择合适的长度。标准IO是在系统调用函数构建的&#xff0c;便于用户使用。 标准IO的所有操作都是围绕流&#x…

如何安装“Ubuntu 20.04桌面版,在win10系统“?

一、 下载 https://ubuntu.com/tutorials/install-ubuntu-desktop#get-ubuntu 二、安装 1、 2、 3、 4、 5、 6、 7、 8、 9、 10、 11、 12、关闭安装&#xff0c;设置-分辨率 13、 14、 15、 16、 17、 18、 19、 20、等待安装 21、

C#,数值计算,希尔伯特矩阵(Hilbert Matrix)的算法与源代码

Hilbert, David (1862-1943) 1 希尔伯特(Hilbert) 德国数学家,在《几何学基础》中提出了第一套严格的几何公理(1899年)。他还证明了自己的系统是自洽的。他发明了一条简单的空间填充曲线,即埃里克魏斯汀的数学世界,即希尔伯特曲线,埃里克魏斯汀的数学世界,并证明了不…

Unity资源热更新----AssetBundle

13.1 资源热更新——AssetBundle1-1_哔哩哔哩_bilibili Resources 性能消耗较大 Resources文件夹大小不能超过2个G 获取AssetBundle中的资源 打包流程 选择图片后点击 创建文件夹&#xff0c;Editor优先编译 打包文件夹位置 using UnityEditor; using UnityEngine; public cla…

v-model 粗略解析

v-model 粗略解析 v-model是什么&#xff1f; 双向数据绑定&#xff0c;可以从data流向页面&#xff0c;也可以从页面流向data通常用于表单收集&#xff0c;v-model 默认绑定 value 值书写形式&#xff1a; v-model:value"" 或 v-model v-model原理是什么&#xf…

C#快速入门基础

本篇文章从最基础的C#编程开始学习&#xff0c;经过非常优秀的面向对象编程思想和方法的学习&#xff0c;为C#编程打下基础。 第 01 章 C#开发环境之VS使用和.NET平台基础 1.1 Visual Studio 开发环境 1.1.1 硬件环境 i5CPUi5CPU&#xff08;建议 4核 4线程或以上 &#xff0…

WebMagic框架

1.webmagic框架 webmagic框架是一个Java实现的爬虫框架&#xff0c;底层依然是HttpClient和jsoup 组件&#xff1a; downloader&#xff1a;下载器组件PageProcessor&#xff1a;页面解析组件&#xff08;必须自定义&#xff09;scheculer&#xff1a;访问队列组件pipeline&am…

Excel数据转sql、json、html

1.Excel转Sql 利用Excel公式CONCATENATE可以实现“insert into table values(”与单元格A1的值拼接&#xff0c;这样一句insert语句就组合好了。 Excel数据&#xff1a; 完整公式&#xff1a; CONCATENATE("INSERT INTO volume(item, volume,update_time) VALUES("…

【测试】构建质量保证之路:编写测试用例的艺术

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Linux ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 1. 确定测试目标&#xff1a; 2. 理解需求和规格&#xff1a; 3. 确定测试条件&#xff1a; 4. 编写测试用例&#xff1a; 结…

drone ci 是什么

Drone CI是一个开源的持续集成和持续部署&#xff08;CI/CD&#xff09;系统&#xff0c;它使用Docker容器技术自动化软件的构建、测试和部署过程。Drone的设计哲学是简单和易用&#xff0c;通过使用Docker容器&#xff0c;它可以很容易地创建隔离的环境来运行测试和部署任务&a…

【Algorithms 4】算法(第4版)学习笔记 17 - 4.3 最小生成树

文章目录 前言参考目录学习笔记1&#xff1a;介绍1.1&#xff1a;定义1.2&#xff1a;应用2&#xff1a;贪心算法 greedy algorithm2.1&#xff1a;简化假设2.2&#xff1a;切分定理2.3&#xff1a;demo 演示2.4&#xff1a;贪心算法的证明2.5&#xff1a;算法实现简要说明2.6&…

数据结构:图及相关算法讲解

图 1.图的基本概念2. 图的存储结构2.1邻接矩阵2.2邻接表2.3两种实现的比较 3.图的遍历3.1 图的广度优先遍历3.2 图的深度优先遍历 4.最小生成树4.1 Kruskal算法4.2 Prim算法4.3 两个算法比较 5.最短路径5.1两个抽象存储5.2单源最短路径--Dijkstra算法5.3单源最短路径--Bellman-…

Python Excel 文本编辑库之xlsxwriter使用详解

概要 在现代数据处理和报表生成中,Excel 文件是一个非常常见的格式。Python XlsxWriter 库是一个强大的工具,可以帮助开发者轻松创建和编辑 Excel 文件,并且具有高度的灵活性和可定制性。本文将全面介绍 XlsxWriter 库的原理、功能、用法,并通过丰富的示例代码来展示其强大…

C++ 作业 24/3/13

1、设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数。 #include <iostream>using namespace std;c…

【老旧小区用电安全谁能管?】安科瑞智慧用电安全管理系统解决方案

行业背景 电气火灾指由电气故障引发的火灾。每年以30%的比例高居各类火灾原因之首。以50%到80%的比例高居重特大火灾之首。已成为业界重点关注的对象并为此进行着孜孜不倦的努力。 国务院安委会也于2017年5月至2020年4月年开展了为期3年的电气火灾综合治理工作。在各界努力的…

微信小程序之vue按钮切换内容变化

效果图如下&#xff1b; 上代码 <template><view class"content"><view class"searchDiv"><view class"paytab"><view class"buttab" v-for"(t,index) in tabList" :key"index" clic…

Address already in dse_JVM_Bind。端口莫名被占用【占用8080端口!!!】

文章目录 问题描述&#xff1a;Address already in dse:JVM_Bind问题可能的原因解决方案 问题描述&#xff1a;Address already in dse:JVM_Bind 问题可能的原因 当前端口已经有别的程序在占用着 我曾经被QQ占用过8080端口&#xff0c;Oracle启动了OracleHttp服务会占用8080端…

接口自动化框架(Pytest+request+Allure)

前言&#xff1a; 接口自动化是指模拟程序接口层面的自动化&#xff0c;由于接口不易变更&#xff0c;维护成本更小&#xff0c;所以深受各大公司的喜爱。 接口自动化包含2个部分&#xff0c;功能性的接口自动化测试和并发接口自动化测试。 本次文章着重介绍第一种&#xff0c…

InstantID Zero-shot Identity-Preserving Generation in Seconds

InstantID: Zero-shot Identity-Preserving Generation in Seconds TL; DR&#xff1a;InstantID IP-Adapter (Face) ControlNet&#xff0c;实现了具有较高保真度的人脸 ID 生成。 方法 InstantID 想做到的事情是&#xff1a;给定一张参考人脸 ID 图片&#xff0c;生成该…