Gradle模块化最佳实践

news2024/9/29 21:33:49

一,模块化的原因及意义

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

  • 代码复用:不同的模块可以共享相同的代码。这样可以避免重复编写相同的代码,提高开发效率。
  • 模块独立性:每个模块都可以独立构建、测试和部署。这样可以降低整个项目的维护成本,例如当有一个模块需要更新时,只需要重新构建该模块而不会影响其他模块。
  • 模块化开发:开发人员可以专注于某个特定的模块,而不需要关心整个项目的复杂性。这样可以提高开发效率和代码质量。
  • 可扩展性:通过定义模块之间的依赖关系,可以方便地引入和管理第三方库和框架。这样可以提高项目的灵活性和可扩展性。

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

二、Gradle介绍

Gradle是一个基于JVM(不止java)的构建工具,用于自动化构建、测试、部署和发布软件项目。它支持多种编程语言,包括Java、Groovy和Kotlin,并且可以与各种开发工具和持续集成系统集成。

相比于老前辈maven,gradle的使用率可就没那么广泛了。maven依然是主导,gradle最大的用户还是Android平台,在其他领域运用依然很少。在java平台,Gradle最著名的项目非spring/springboot莫属了。

2.1Gradle后发优势

相比于maven,gradle具有以下优势:

  • 灵活性:代码即脚本,可以直接使用Groovy或Kotlin编写脚本,而Maven则需要转化为xml格式的插件,非常麻烦。
  • 性能:Gradle具有更好的构建性能。它使用增量编译和缓存机制,只重新构建有变更的部分,从而提高构建速度。而Maven则没有这样的机制,每次都会重新编译所有文件。这尤其在大型项目中能够显著减少构建时间。
  • 可读性:Gradle的构建脚本更易读和维护。它使用了一种声明性的语法,能够更清晰地表达构建逻辑和依赖关系。而Maven的XML格式相对较冗长和繁琐,不太直观。

2.2Gradle的劣势

有优势就肯定有劣势,如果gradle全面领先的话,那还有maven什么事呢?gradle存在以下劣势:

  • 学习曲线:相较于Maven,Gradle的学习曲线较陡峭。由于Gradle提供了更灵活的构建脚本语法和更强大的插件系统,初学者可能需要花费一些时间来熟悉和理解Gradle的概念和用法。主要是比较难入门,让很多人从入门到放弃
  • 文档和社区支持:相较于Maven,Gradle的生态支持相对较少。由于Maven出道早,运用广泛,在文档和社区方面更为成熟和丰富。

前一篇文章《Maven模块化最佳实践》介绍了如何使用maven进行模块化开发,本文继续讲述如何使用gradle进行模块化开发。

三,模块化的继承效果

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

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

3.1继承配置

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

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

ext {
	nettyVersion         = "4.1.33.Final"
	minaVersion 		 = "2.0.7"
    springBootVersion 	 = '2.6.0'
    gsonVersion 		 = "2.8.0"
    mysqlVersion 		 = "5.1.6"
	jacksonVersion		 = "2.12.1"
	protostuffVersion    = "1.5.9"
	protobufVersion 	 = "1.11.7"

}

3.2继承依赖

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

3.2.1统一申明子模块的依赖,避免子模块直接依赖冲突。

dependencies {
		api ("org.springframework.boot:spring-boot-dependencies:${springBootVersion}")
		api 'org.apache.commons:commons-lang3:3.4'
		
		compileOnly 'org.projectlombok:lombok:1.18.6'
		annotationProcessor 'org.projectlombok:lombok:1.18.6'
	
		implementation ("com.google.code.gson:gson:${gsonVersion}")

		implementation ("io.netty:netty-all:${nettyVersion}")
}

 3.2.2子模块统一模块

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

subprojects {
	dependencies {
		testImplementation ("junit:junit:${junitVersion}")
		testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
		testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
	}
}

3.3继承任务(task)

maven通过插件(plugin)来构建项目命令,而gradle通过任务(task)。task直接用脚本语言书写,不用封装,非常灵活。

maven的插件继承,子模块可以使用并覆写某些配置。而gradle的task继承更像OOP,子模块可以在子任务中使用父任务的属性和方法,例如通过super关键字来调用父任务的方法。使用如下:

1.在build.gradle文件中定义一个父任务(例如,名为parentTask),并为其添加所需的配置和行为。例如:

task parentTask {
    // 添加父任务的配置和行为
    doLast {
        println 'This is the parent task'
    }
}

 ​​​​​​2.在build.gradle文件中定义一个子任务(例如,名为childTask),并使用extends关键字继承父任务。例如:

task childTask(type: parentTask) {
    // 添加子任务的配置和行为
    doLast {
        println 'This is the child task'
    }
}

四、模块化的聚合效果

在Gradle中,聚合是指将多个子项目合并为一个大项目进行构建。聚合可以帮助您管理包含多个相关项目的大型代码库。以下是如何在Gradle中进行聚合的步骤:

创建一个父项目文件夹,并在该文件夹下创建一个settings.gradle文件。添加需要聚合的子模块,例如mmorpg的配置

rootProject.name = 'mmorpg'

include 'game-common', 'game-protocol', 'game-net', 'game-data-starter',
		'game-server','game-mq', 'game-rpc'

在父项目文件夹中运行Gradle命令,例如gradle build。Gradle将会自动聚合并构建父项目及其所有子项目。

五、重命名子模块的脚本名称

maven使用pom.xml来构建管理任务,不管是父模块还是子模块,都是一样的名字,这样在查找文件的时候不够方便。而Gradle则运行给子模块重命名。在setting.gradle下输入以下命令

// 修改子项目的build文件名,重名很难查找
rootProject.children.each {
	it.buildFileName = it.name - "game-" + ".gradle"
}

每个子模块独立名字 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql数据库-基本表操作

1.表操作 创建表:CREATE TABLE table_name ( field1 datatype, field2 datatype, field3 datatype ) character set 字符集 collate 校验规则 engine 存储引擎; field 表示列名 datatype 表示列的类型 character set 字符集,如果没有指定字符集&#xff…

单文件组件SFC及Vue CLI脚手架的安装使用

单文件组件SFC及Vue CLI脚手架的安装使用 Vue 单文件组件(又名 *.vue 文件,缩写为 SFC)是一种特殊的文件格式,它允许将 Vue 组件的模板、逻辑 与 样式封装在单个文件中。 为什么要使用 SFC 使用 SFC 必须使用构建工具&#xff…

js实现文本内容过长中间显示...两端正常展示

实现思路 获取标题盒子的真实宽度, 我这里用的是clientWidth;获取文本内容所占的实际宽度;根据文字的大小计算出每个文字所占的宽度;判断文本内容的实际宽度是否超出了标题盒子的宽度;通过文字所占的宽度累加之和与标题盒子的宽度…

05 排序与分页

排序与分页 1 排序数据 1.1 排序规则 使用 ORDER BY 子句排序 ASC(ascend): 升序DESC(descend):降序 ORDER BY 子句在SELECT语句的结尾 1.2 单列排序 SELECT last_name, job_id, department_id, hire_date FROM empl…

蓝桥杯备战刷题-滑动窗口

今天给大家带来的是滑动窗口的类型题,都是十分经典的。 1,无重复字符的最长子串 看例三,我们顺便来说一下子串和子序列的含义 子串是从字符串里面抽出来的一部分,不可以有间隔,顺序也不能打乱。 子序列也是从字符串里…

数据分析-Pandas画分布密度图

数据分析-Pandas画分布密度图 数据分析和处理中,难免会遇到各种数据,那么数据呈现怎样的规律呢?不管金融数据,风控数据,营销数据等等,莫不如此。如何通过图示展示数据的规律? 数据表&#xff…

CAE模拟仿真工具CEETRON Envision:大数据可视化助力工业设计与协同

行业: 制造业; 工业设计; 汽车;航天 挑战:工业客户需要有效的方法来处理CAE数据;ESTECO寻求提供CAE可视化功能来帮助客户做出决策;许多可用的可视化工具无法提供对模型中数据的完全访问以进行深入分析 解决方案&…

Linux智能网关结合Node-RED实现实时工业数据采集

工业4.0的发展,物联网技术在制造业中的应用越来越广泛。其中,基于Linux系统的工业物联网智能网关因其开放性、稳定性和安全性而备受青睐。这类智能网关创新性地集成了开源工具Node-RED,为从各种工业设备(如PLC)中高效收…

前端学习之行内和块级标签

行内标签 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>span</title> </head> <body><!-- 行内标签特点&#xff1a;1、不换行,一行可以放多个2、默认宽度内容撑开代表&#…

Python中eval与exec的使用及区别

最近开发中用到了eval()与exec()这两个函数&#xff0c;不知道在哪种场景下用哪个函数&#xff0c;所以就翻了下Python的文档。这里就来简单说一下这两个函数的区别 1. eval函数 函数的作用&#xff1a; 计算指定表达式的值。也就是说它要执行的Python代码只能是单个运算表达…

虚拟机实验环境配置与使用(计算机系统2)

一、 实验目标&#xff1a; 熟悉Linux上C程序的编译和调试工具&#xff0c;包括以下内容&#xff1a; 1. 了解Linux操作系统及其常用命令 2. 掌握编译工具gcc的基本用法 3. 掌握使用gdb进行程序调试 二、实验环境与工件 1.个人电脑 2. Fedora 13 Linux 操作系统 3. gcc…

YOLOV5 初体验:简单猫和老鼠数据集模型训练

1、前言 前两天&#xff0c;通过OpenCV 对猫和老鼠视频的抽取&#xff0c;提取了48张图片。这里不再介绍&#xff0c;可以参考之前的文章&#xff1a;利用OpenCV 抽取视频的图片&#xff0c;并制作目标检测数据集-CSDN博客 数据的目录如下&#xff1a; 项目的下载见文末 2、制…

Storyboard动画、EventTrigger事件触发器

就是动画&#xff0c;要注意的就是EventTrigger中的SourceName就是想要实现这个功能的按钮 <StackPanel Orientation"Vertical"><Rectanglex:Name"rect"Width"200"Height"40"Fill"Pink" /><StackPanel Orie…

Vue3学习记录(六)--- 组合式API之依赖注入和异步组件

一、依赖注入 1、简介 ​ 在前面的笔记中&#xff0c;我们学习过父组件向子组件传递数据时&#xff0c;需要借助props来实现。但如果父组件想要向孙子组件传递数据&#xff0c;那就要连续使用两层props逐级向下传递&#xff0c;如果要接收数据的是更深层的后代组件&#xff0…

同一交换机下不同网段的终端通信

文章目录 一个有趣的实验 大家都知道不同网段的IP地址要想通信需要通过网关进行路由转发&#xff0c;而一般通过路由器来做默认网关。 一个有趣的实验 一台二层交换机下&#xff0c;连接两个不同网段的PC&#xff0c;实现彼此之间的通信。 一台S3700交换机&#xff0c;两台PC。…

【金三银四】Spring面试题

目录 1、什么是Spring2、说一下Spring的IOC3、Spring的AOP4、连接点&#xff1f;切入点&#xff1f;5、Spring AOP 是通过什么实现的6、Spring Bean的生命周期是怎么样的&#xff1f;7、Spring Bean的初始化过程是怎么样8、Spring的事务传播机制有哪些&#xff1f;9、Autowired…

Qt 中Json文件的操作

Json文件的读取 QFile file("data.json"); //准备好的文件file.open(QIODevice::ReadOnly|QIODevice::Text);QByteArray arr file.readAll();QJsonDocument jsonDoc QJsonDocument::fromJson(arr);QJsonObject jsonObj jsonDoc.object();qint32 id jsonObj["…

网络工程师笔记10 ( RIP / OSPF协议 )

RIP 学习路由信息的时候需要配认证 RIP规定超过15跳认定网络不可达 链路状态路由协议-OSPF 1. 产生lsa 2. 生成LSDB数据库 3. 进行spf算法&#xff0c;生成最有最短路径 4. 得出路由表

Python错题集-8:AttributeError(找不到对应的对象的属性)

1问题描述 AttributeError: AxesSubplot object has no attribute arc 2代码详情 import matplotlib.pyplot as plt# 创建一个新的图形和坐标轴 fig, ax plt.subplots()# 定义弧线的参数 center (0.5, 0.5) # 圆心坐标 (x, y) width 1.0 # 半径 height 0.5 # 半径 ang…

学习笔记。。。

1.字符串的拼接 1.sprintf() 往字符串的前面或中间、后面拼接一个字符串。 2.strncpy()用来复制字符串的前n个字符 //dest为目标数组&#xff0c;src为源数组&#xff0c;n为要复制的字符个数 2.char* My_strncpy(char* dest, const char* src, int n) 3.char *strcat(ch…