Maven模块化最佳实践
一,模块化的原因及意义
模块化是一种将大型的软件系统拆分成相互独立的模块的方法。具有以下优势:
-
代码复用:不同的模块可以共享相同的代码。这样可以避免重复编写相同的代码,提高开发效率。
-
模块独立性:每个模块都可以独立构建、测试和部署。这样可以降低整个项目的维护成本,例如当有一个模块需要更新时,只需要重新构建该模块而不会影响其他模块。
-
模块化开发:开发人员可以专注于某个特定的模块,而不需要关心整个项目的复杂性。这样可以提高开发效率和代码质量。
-
可扩展性:通过定义模块之间的依赖关系,可以方便地引入和管理第三方库和框架。这样可以提高项目的灵活性和可扩展性。
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的继承和聚合是相辅相成的,一般都是整合起来用。
相关文章:
Maven模块化最佳实践
一,模块化的原因及意义 模块化是一种将大型的软件系统拆分成相互独立的模块的方法。具有以下优势: 代码复用:不同的模块可以共享相同的代码。这样可以避免重复编写相同的代码,提高开发效率。 模块独立性:每个模块都可…...

嵌入式C语言中 #pragma once 的作用
1、#pragma once有什么作用? 为了避免同一个头文件被包含(include)多次,C/C中有两种宏实现方式: 一种是#ifndef方式; 另一种是#pragma once方式。 在能够支持这两种方式的编译器上,二者并没…...

spring-cloud-openfeign 3.0.0(对应spring boot 2.4.x之前版本)之前版本feign整合ribbon请求流程
在之前写的文章配置基础上 https://blog.csdn.net/zlpzlpzyd/article/details/136060312 下图为自己整理的...

#数据结构 线性表的顺序存储
目录 每日文案 一、线性表的定义 二、线性表的操作 顺序表的存储结构 顺序表的初始化操作 判断顺序表是否为空表 将顺序表置为空表 计算顺序表中的元素个数 取出顺序表中的对应位置元素 取出对应数值的位序 在对应位置插入元素 将对应位置的元素删除 将顺序表中的数据…...

[iOS]高版本MacOS运行低版本Xcode
Xcode 版本支持文档 目的: 在MacOS Sonoma 系统上安装 Xcode14.3.1 第一步 先在Xcode下载一个Xcode14.3.1的压缩包 第二步 本地解压Xcode,将外层目录名变更为Xcode_14.3.1,将文件拷贝到 /Applications目录下。 第三步 变更xcode-sel…...

仿牛客项目Day5:开发登录、退出功能
登录功能 数据库 创建了一个表login_ticket来记录登录凭证,类似于session 核心字段是ticket entity 创建了一个类loginTicket mapper 处理login_ticket的mapper接口层,用来往里面查询数据、增加数据和修改数据 查询数据通过ticket来查 select是通…...

Vue3全家桶 - Vue3 - 【3】模板语法(指令+修饰符 + v-model语法糖)
一、模板语法 主要还是记录一些指令的使用和vue2的区别;vue3指令导航; 1.1 v-text 和 v-html 指令的区别: v-text: 更新元素的文本内容;v-text 通过设置元素的 textContent 属性来工作,因此它将覆盖元素…...

OpenCV开发笔记(七十七):相机标定(二):通过棋盘标定计算相机内参矩阵矫正畸变摄像头图像
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/136616551 各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究 红胖子(红模仿)的博…...

2024蓝桥杯每日一题(时间日期)
一、第一题:日期差值 解题思路:模拟 写一个计算时间的板子两者相减 【Python程序代码】 mon [0,31,28,31,30,31,30,31,31,30,31,30,31] def pd(x):if x%4000 or (x%40 and x%100!0):return Truereturn False def get_day(y,m,d):res 0for i …...
js【详解】事件
给 DOM 节点绑定事件 推荐使用 addEventListener 函数 第一个参数:事件名称第二个参数:事件处理函数(第一个参数为 event)第三个参数: true 采用捕获法来处理事件false 【推荐】采用冒泡法来处理事件 let div1 docu…...
webpack5基础--14_优化css
Css 处理 提取 Css 成单独文件 Css 文件目前被打包到 js 文件中,当 js 文件加载时,会创建一个 style 标签来生成样式 这样对于网站来说,会出现闪屏现象,用户体验不好 我们应该是单独的 Css 文件,通过 link 标签加载…...

Skywalking(9.7.0) 告警配置
图片被吞,来这里看吧:https://juejin.cn/post/7344567669893021736 过年前一天发版,大家高高兴兴准备回家过年去了。这时候老板说了一句,记得带上电脑,关注用户反馈。有紧急问题在高速上都得给我找个服务区改好。 但是…...
删除、创建、验证Kafka安装自带的__consumer_offsets topic
删除Kafka自带Topic 一般情况下,你删除Kafka自带的__consumer_offsets topic,会报错提示不能删除。 倔强的你直接找到zookeeper删掉了它,list查看确实没有这个topic了,但是这会导致消费者和偏移量无法记录。 创建Kafka自带的Topi…...

在文件夹下快速创建vue项目搭建vue框架详细步骤
一、首先在你的电脑目录下新建一个文件夹 进入该文件夹并打开控制台(输入cmd指令) 进入控制台后输入 vue create springboot_vue (自己指定名称) 如果出现这类报错如:npm install 的报错npm ERR! network request to http://registry.cnp…...

蓝桥杯倒计时 36天-DFS练习
文章目录 飞机降落仙境诅咒小怂爱水洼串变换 飞机降落 思路:贪心暴搜。 #include<bits/stdc.h>using namespace std; const int N 10; int t,n; //这题 N 比较小,可以用暴力搜搜复杂度是 TN*N! struct plane{int t,d,l; }p[N]; bool vis[N];//用…...

ctfshow web入门 php特性总结
1.web89 intval函数的利用,intval函数获取变量的整数值,失败时返回0,空的数组返回,非空数组返回1 num[]1 intval ( mixed $var [, int $base 10 ] ) : int Note: 如果 base 是 0,通过检测 var 的格式来决定使用的进…...

Media Encoder 2024:未来媒体编码的新纪元 mac/win版
随着科技的飞速发展,媒体内容已成为我们日常生活中不可或缺的一部分。为了满足用户对高质量视频内容不断增长的需求,Media Encoder 2024应运而生,它凭借卓越的技术和创新的特性,重塑了媒体编码的未来。 Media Encoder 2024 mac/w…...
2024年AI辅助研发趋势:数智时代革新新引擎
随着科技的飞速发展,人工智能(AI)已经渗透到我们生活的方方面面,而在软件开发领域,AI辅助研发正成为一股不可忽视的力量。本文将探讨2024年AI辅助研发的趋势,以及它如何成为数智时代革新的新引擎。 AI辅助研…...

2024年家政预约上门服务小程序【用户端+商家端+师傅端】源码
024最新家政预约上门服务小程序源码 主要功能:商家入住,师傅入住,缴纳保正金 支持师傅,抢单派单 支持多城市多门下单,支持预约上门服务到店核销 支持补差价义价,支持区域服务限制 基于thinkphp和原生小程序开发...

数据结构:静态链表(编程技巧)
链表的元素用数组存储, 用数组的下标模拟指针。 一、理解 如果有些程序设计语言没有指针类型,如何实现链表? 在使用指针类型实现链表时,我们很容易就可以直接在内存中新建一块地址用于创建下一个结点,在逻辑上&#x…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...

LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...

高考志愿填报管理系统---开发介绍
高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发,采用现代化的Web技术,为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## 📋 系统概述 ### 🎯 系统定…...