当前位置: 首页 > news >正文

浅谈Gradle构建工具

一、序言

常见的项目构建工具有Ant、Maven、Gradle,以往项目常见采用Maven进构建,但随着技术的发展,越来越多的项目采用Gradle进行构建,例如 Spring-boot。Gradle站在了Ant和Maven构建工具的肩膀上,使用强大的表达式语言Groovy或者Kotlin使其具有易用、灵活的方式自定义构建逻辑,方便扩展,更加适合大型项目构建。

二、性能对比

相比Maven,Gradle为了提高构建的效率,提出了增量构建的概念。Gradle中是以 task 为单位,将一个task分input、任务本身和output。例如下图:input是jdk版本和源文件,output是变异后的class文件。构建的原理就是监听input的变化,当input发生变化的时候,Gradle才会重新构建,否则认为可以复用之前的构建结果。
在这里插入图片描述
Gradle可以重用同样的input作为缓存,相比增量编译,缓存则可以跨机器共享,当构建的时候,可以直接从CI服务器拉取构建结果,非常方便。除此之外,Gradle还会开启一个守护进程来处理跟各个build任务的交互,所以不需要每次构建都初始化组件和服务。守护进程默认是开启的,可以通过gradle –status查看运行的守护进程。
在这里插入图片描述
这是Gradle和Maven分别构建Apache Commons Lang3耗时的对比,可以看到Gradle的性能提升是很明显的。
在这里插入图片描述

二、构建生命周期

Gradle构建的生命周期可以简单划分为初始化、配置和执行,在生命周期各个阶段都提供了用于回调的钩子函数,方便我们监听整个构建过程。
在这里插入图片描述
上图是简单的钩子函数示例,依赖钩子函数就可以监听构建的过程

// Setting 项目编译前调用
gradle.beforeProject {// 在这里写明显无用println("gradle.beforeProject...")
}// 所有项目脚本执行完后调用
gradle.buildFinished {println("gradle.buildFinished ...")
}

除了上面的钩子函数,Gradle也包含其他的钩子函数,比如 settingsEvaluated、projectsEvaluated等,网上资料挺多,这里就不再赘述。

三、依赖管理

Gradle也是依赖Maven的仓库用于Jar包的管理,同样也有本地仓库和中央仓库,也可以配置私服,这一点跟Maven的同样的概念的。举个栗子,下面的代码就指定了对应的本地仓库、中央仓库和私服。

buildscript {repositories {mavenLocal()maven {credentials {// 认证信息 配置私服的用户名和密码}url = 'https://nexus.xxx.cn/repository/public/'}mavenCentral()}dependencies {classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.3.RELEASE")}
}

Gradle会按照配置顺序进行依赖包的加载和扫描,依赖包通过dependencies定义,跟Maven类似,同样需要指定包名和版本号来定位。

dependencies {testImplementation("org.springframework.boot:spring-boot-starter-test:2.1.3.RELEASE")api("org.springframework.boot:spring-boot-starter-amqp:2.1.3.RELEASE")api 'com.google.cloud:google-cloud-storage:2.4.0'annotationProcessor "org.projectlombok:lombok:1.18.24"
}

在dependencies中,包含多种类型指定项目依赖项,整体如下:

类型含义
implementation依赖项是会在编译和运行时使用,不会传递给依赖于你的项目的其他模块
api依赖项是项目的公共 API 依赖项,会在编译、运行和其他依赖于你的项目的模块的编译时使用;如果你的模块是一个库模块,希望这些依赖项对外可见,那么可以使用该关键字
compileOnly依赖项仅在编译时使用,不会被打包到最终的构建产物中
runtimeOnly依赖项仅在编译时使用,不会被打包到最终的构建产物中
testImplementation依赖项仅在测试编译和执行测试时使用,不会传递给项目的主要编译路径
testCompileOnly类似于 compileOnly,但仅适用于测试编译路径
testRuntimeOnly类似于 runtimeOnly,但仅适用于测试运行路径
annotationProcessor依赖项是用于编译时注解处理的依赖项,例如lombok的依赖项

四、依赖版本冲突

在项目实际的构建过程中经常依赖包版本冲突的问题,Maven中可以通过 exclude 的方式移除冲突的包,Gradle其实也类似。遇到依赖包冲突,首先是查看依赖报告,可以排除传递性依赖或者强制指定一个版本。

通过exclude排除传递性依赖

dependencies {implementation('com.example:library') {exclude group: 'org.unwanted', module: 'unwanted-module'}
}

使用force强制指定一个版本

dependencies {resolutionStrategy {force 'com.example:library:1.0.0'}
}

如果强制指定了两个相同的包,只是版本不一样,具体选择哪个版本取决于 Gradle 解析依赖的规则,默认情况下会选择最高版本进行解析。

五、多项目构建

在实际开发过程中,通常都是多个模块进行构建,类似Maven提供Parent的方式用来传递模块依赖关系,Gradle也同样提供了多项目构建的方法,用于统一配置公共属性和依赖。

allprojects {apply plugin: 'java-library'apply plugin: 'io.spring.dependency-management'apply plugin: 'maven-publish'// JVM 版本号要求sourceCompatibility = 1.8targetCompatibility = 1.8
}

allprojects 中用来声明所有子模块的通用配置,能在 build.gradle 中配置的语法也都可以同样在allprojects中编写。

另外,Gradle提供 gradle.properties 文件用来统一声明版本号,类似Maven的 properties标签,方便依赖包版本的统一管理。

举个栗子:

springBootVersion=2.1.3.RELEASE
springBootGradlePluginVersion=2.1.3.RELEASE

声明了依赖包SpringBoot和对应Gradle插件的版本,那么依赖配置项则可以修改为如下

dependencies {testImplementation("org.springframework.boot:spring-boot-starter-test:${springBootVersion}")api("org.springframework.boot:spring-boot-starter-amqp:${springBootVersion}")
}

六、自动化测试

想要实现Gradle的自动化测试,需要配置测试依赖项,比如这里引入junit4作为测试。

dependencies {testImplementation 'junit:junit:4.12'
}

编写相应的测试用例,用 @Test 注解来标记测试方法。Gradle提供了内置的测试任务,使用 gradle test 命令可以方便地运行测试用例并生成测试报告,包括测试结果和覆盖率等信息,提供 HTML 可视化图表,测试报告通常位于build/reports/tests目录下。所以可以将其集成到CI流程中,每次代码提交或构建的时候就能生成相应的报告,还是很直观的。

七、总结

除了上面的内容,Gradle还有很多个性化的用法,比如自定义task等操作来控制构建的流程。因为我之前一直用的都是Maven工具,本身也是Gradle的初学者,最近也是因为新项目而接触Gradle,如果文章有什么错误的地方,也欢迎大家指出,一起学习交流。

相关文章:

浅谈Gradle构建工具

一、序言 常见的项目构建工具有Ant、Maven、Gradle,以往项目常见采用Maven进构建,但随着技术的发展,越来越多的项目采用Gradle进行构建,例如 Spring-boot。Gradle站在了Ant和Maven构建工具的肩膀上,使用强大的表达式语…...

如何获取和制作免费的icon图标素材

icon 图标在界面设计中虽然占比不大,但却是不可缺少的设计元素之一。设计师通过 icon 图标,将抽象的概念通俗化,降低用户理解某个操作的难度。而设计师也会通过改变 icon 图标的样式来展现整体界面的视觉效果。icon 图标的风格有很多&#xf…...

【MySQL】MySQL索引--聚簇索引和非聚簇索引的区别

文章目录 前言1.聚簇索引和非聚簇索引的概念2.两者详细介绍2.1 聚簇索引2.2 非聚簇索引 3. 两者的区别3.1 数据存储方式3.2 二级索引查询 前言 1.聚簇索引和非聚簇索引的概念 数据库表的索引从数据存储方式上可以分为聚簇索引和非聚簇索引两种。“聚簇”的意思是数据行被按照…...

如何使用 SVG.js 中的一些相关方法来创建、设置和操作 image 元素

SVG.js 是一个基于 JavaScript 的 SVG 库,提供了许多常用的 SVG 元素和方法,方便开发者进行 SVG 图形的创建和操作。其中,image 元素是 SVG.js 中较为常用的元素之一,本文将详细介绍 SVG.js 中与 image 元素相关的方法。 一、创建…...

展会进行时!5月16-18日箱讯与您相约中国航交会

宁波国际会展中心7、8号馆 第五届中国(宁波)国际航运物流交易会 暨2023全球物流企业合作博览会 火爆进行中 箱讯与您相约 8号馆 C033K-C036展位 期待您的光临! 2023年5月16-18日,第五届中国(宁波)国际…...

CMake:递归检查并拷贝所有需要的DLL文件

文章目录 1. 目的2. 设计整体思路多层依赖的处理获取 DLL 所在目录探测剩余的 DLL 文件 3. 代码实现判断 stack 是否为空判断 stack 是否为空获取所有 target检测并拷贝 DLL 4. 使用 1. 目的 在基于 CMake 构建的 C/C 工程中,拷贝当前工程需要的每个DLL文件到 Visu…...

python常见问题及解决方案

Python是一种高级编程语言,具有易于学习、易于阅读和易于维护的特点。然而,即使是最有经验的Python开发人员也可能会遇到一些常见的错误。在本文中,我们将讨论一些常见的Python运行时错误,并提供解决这些错误的办法。 语法错误 …...

JUC之Synchronized与Lock

Synchronized 称之为”同步锁 作用: 保证在同一时刻, 被修饰的代码块或方法只会有一个线程执行,以达到保证并发安全的效果 用法: 1.修饰方法:方法锁,锁的对象是当前对象 2.修饰静态方法:类锁…...

动态规划理论基础

文章目录 定义动态规划与分治问题的区别两种方式实现动态规划方法一:带备忘录的自顶向下法方法二:自底向上法 本质核心解题步骤常见题型划分 定义 动态规划方法通常用来求解最优化问题(optimization problem)。这类问题可以有很多可行解,每个…...

Redis的数据类型

参考文档:https://www.runoob.com/redis/redis-tutorial.html redis当中一共支持五种数据类型,分别是: string字符串 list列表 set集合 hash表 zset有序集合 1、对字符串string的操作 下表列出了常用的 redis 字符串命令 1 设置值 获取…...

vue3鼠标经过显示按钮

在前端开发中,我们经常需要在页面中添加一些交互效果来提升用户体验。其中一个常见的需求就是鼠标经过某个元素时显示一个按钮,这个按钮可以用于触发一些操作或者显示更多的内容。 在本篇文章中,我将会介绍如何使用 Vue3 实现一个鼠标经过显…...

【2023华为OD笔试必会25题--C语言版】《18 最短木板长度》——数组

本专栏收录了华为OD 2022 Q4和2023Q1笔试题目,100分类别中的出现频率最高(至少出现100次)的25道,每篇文章包括原始题目 和 我亲自编写并在Visual Studio中运行成功的C语言代码。 仅供参考、启发使用,切不可照搬、照抄,查重倒是可以过,但后面的技术面试还是会暴露的。✨✨…...

yolov5车道线检测+测距(碰撞检测)

yolov5车道线检测+测距(碰撞检测) 1. 车道线检测2. 测距2.1 测距原理2.2 相机标定2.2.1:标定方法12.2.2:标定方法23. 相机测距3.1 测距添加3.2 主代码4. 实验结果相关链接 1. 基于yolov5的车道线检测及安卓部署 2. YOLOv5+单目测距(python) 3. 具体实现效果...

微服务学习笔记--(Gateway网关)

统一网关Gateway 为什么需要网关gateway快速入门断言工厂过滤器工厂全局过滤器跨域问题 Gateway网关-网关作用介绍 为什么需要网关 网关功能: 身份认证和权限校验服务路由、负载均衡请求限流 网关的技术实现 在SpringCloud中网关的实现包括两种: …...

QML插件的创建及调用

QML插件的创建及调用 创建QML Plugin注册插件调用插件 创建QML Plugin 1、 注册插件 1、可以将qml文件放在qmldir中进行声明。 此种方式需要将qml文件和qmldir放在一起 module EularFrame plugin EularFrameEButton 1.0 MyButton.qml2、可以在*plugin.cpp注册 此种方式只需…...

数据结构学习分享之树的介绍

💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:数据结构学习分享⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你了解更多数据结构的知识   🔝🔝 数据结构第六课 1. 前言&a…...

MySQL数据库基础2

文章目录 数据类型表的约束 数据类型 1、数值类型:BIT、TINYINT、BOOL、SMALLINT、INT、BIGINT、FLOAT[(M,D)]、DOUBLE[(M,D)]、DECIMAL[(M,D)] FLOAT[(M,D)]:占用四个字节,M表示显示位数,D表示小数位数,精度保证&am…...

AutoSAR PNC和ComM

文章目录 PNC和ComMPNC管理NM PDU结构及PNC信息位置如何理解节点关联PNCPNC状态管理 ComM 通道状态管理 PNC和ComM PNC 和 ComM层的Channel不是一个概念,ComM的Channel对应具体的物理总线数。 在ComM模块中,一个Channel可以对应一个PNC,也可…...

Android studio Camera2实现的详细流程

流程 一、获取CameraManager实例二、获取可用的相机列表三、选择一个相机并打开它四、创建一个CaptureRequest.Builder对象五、设置CaptureRequest.Builder对象的参数六、创建一个CaptureSession对象七、开始预览 代码示例 一、获取CameraManager实例 CameraManager manager (…...

阿里云数据库ClickHouse产品和技术解读

摘要:社区ClickHouse的单机引擎性能十分惊艳,但是部署运维ClickHouse集群,以及troubleshoot都不是很好上手。本次分享阿里云数据库ClickHouse产品能力和特性,包含同步MySQL库、ODPS库、本地盘及多盘性价比实例以及自建集群上云的迁…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...