文章目录
1.概述
Task 是 Gradle 构建脚本中的基本执行单元,它们代表了需要执行的具体工作,例如编译代码、打包应用程序、运行测试、生成文档等各种操作。
在 Gradle 的生态系统中,几乎所有的构建过程都是由一个个 Task 组装而成的,可以说 Gradle 的强大和灵活性很大程度上源于其 Task 的设计和实现。理解和掌握 Task 的概念和使用方法,通过精确地配置和管理 Task,可以实现高效、灵活和可扩展的构建流程。
因此,深入理解 Task 是掌握 Gradle 的关键。本篇将会带你认识和使用 Task,并在这个基础上编写自己的自定义 Task。
有一定经验和英语阅读能力的同学,建议直接阅读官方文档。附:《Task官方文档》
2.认识Task
Task 就是组成 Gradle 的基本执行单元,但 Gradle 自带的 Task 很少,大多数的 Task 是来自于plugin
也就是 Gradle 的插件。
在本篇中不会涉及插件的内容讲解,如果感兴趣的话可以关注我的下一篇文章。
2.1.查看Task列表、认识分组和描述
以之前的文章中的SpringBoot项目为例,可以通过gradlew tasks
指令来查询当前模块下能够执行的 Task。
./gradlew :demo-service:tasks
图中的白色字体 Build tasks
,Documentation tasks
指的是任务的分组(group
),绿色字体则是tasks
,后面的黄色字体则是当前 Task 的描述(description
)。这种方式查看已经比较直观了,不过如果是使用IDEA的话,还有一种更方便的方式,可以直接在右侧的 gradle 面板中查看每一个模块,每一个分类中的Task。
使用这种方式,外层的application
,build
就是分组,点进去的bootRun
就是 Task,鼠标移动上去了之后显示的tips
就是定义的描述。
这三者的定义是在注册 Task 的时候写的,例如在build.gradle
中可以这么写:
tasks.register('hello') {
group = 'myTaskGroup'
description = 'This is my task group'
}
2.2.Task的类型
gradle 中定义了 Task 的两种类型,分别是生命周期任务(Lifecycle tasks)与可执行任务(Actionable tasks)
- 生命周期任务(Lifecycle tasks):是一种特殊类型的任务,其主要作用是管理和控制其他任务的执行顺序,而不直接执行任何具体的操作。这类任务通常用于定义构建过程中的阶段性目标,如
clean
、build
等 - 可执行任务(Actionable tasks):是 Gradle 中最常见的任务类型,它们包含实际的执行动作(actions),完成具体的构建操作。这类任务可以执行编译、测试、打包等操作。
如果了解 Maven 的话,两种任务类似于 Maven 生命周期中的 phase
和 goal
,感兴趣的话可以看看我的另一篇 Maven 文章:《详细聊聊 Maven 的生命周期、阶段(phase)、插件目标(goal)》。
通俗的讲,生命周期任务就是定义了一条构建流程而不做具体的实现,通过可执行任务去填充一个一个的流程节点,生命周期任务负责组织和协调,可执行任务负责实际的执行和操作,互相配合确保构建过程的有序和高效。
3.使用Task
3.1.Task的任务执行结果
查看到可用的 Task 之后,可以使用 gradlew :taskName
来执行对应的 Task,例如:gradlew build
就是用来执行构建任务的,当然也鼠标双击使用 IDEA 右侧的 gradle 面板中的 Task选项来使用,我们现在尝试使用一下demo-service
中的build
操作。
可以看到图中按顺序打印出了执行的 Task,按冒号做分割,图中第二列指的是项目名称,第三列是 Task 的名称,最后一列是执行结果的分析和优化。
- EXECUTED(或没有Label):任务被实际执行,是最常见的执行结果。
- UP-TO-DATE:表示该任务的输入和输出自上次执行后没有发生变化,因此任务被跳过。一般在增量构建中出现。
- NO-SOURCE:任务没有可供处理的输入文件,因此任务被跳过。
- FROM-CACHE:任务的输出结果是从缓存中恢复的,而不是重新执行任务
- SKIPPED: 表示任务被明确跳过,任务可以通过某些条件被配置为跳过执行。
在这里是先将依赖的demo-api
打成jar包了之后,再对demo-service
做了编译,构建可以执行jar包,源码包,测试代码构建,测试代码执行等操作。
3.2.增量任务(Incremental Task)
增量任务是 Gradle 中的一种特性,表示的是在一个复杂的构建流程中,其中的一部分任务输入和输出都没有发生变化(通过检查输入和输出文件的时间戳和内容哈希值),就不需要重新执行这些任务,而是直接使用上次的结果,对于发生了变化的部分,则重新进行构建。
例如:上图的构建,如果我仅修改demo-service
中的代码,而不对demo-api
进行修改,此时demo-api
未发生变化,那么就无需重新执行编译等任务,运行结果即为UP-TO-DATE,如下图:
3.3.缓存任务(Caching Task)
缓存任务和上面的增量任务很类似,就是在执行构建流程的时候如果任务输入没有发生变化(也是检查时间戳和内容哈希值),就从构建缓存里面恢复(FROM-CACHE)任务输出而不是重新执行构建任务。
UP-TO-DATE的优先级高于FROM-CACHE,即如果输入输出没有变化,则不会执行构建任务也不会从缓存中恢复,在输入文件相同但输出文件不存在(例如 clean 之后)的情况下,才会尝试通过缓存恢复。 优先级如下:
缓存任务是默认关闭的,有两种方式可以开启
- 一种是通过
gralde.properties
文件中加入全局配置,org.gradle.caching=true
- 另一种是在执行 Task 时,加入
--build-cache
,例如:
在IDEA中,可以编辑右侧 Gradle 面板中的 Task 属性来实现:./gradlew :demo-service:build --build-cache
在clean
并执行build
后,可以看到 Task 的执行结果变成了FROM-CACHE
3.5.跳过任务执行
在构建的生命周期中,如果不想执行其中的某些 Task,可以选择跳过这个任务,例如在整个build
流程中,我并不行执行test
这个任务,我们就可以在build.gradle
中禁用这个任务。禁用方式如下:
compileTestJava.enabled = false
test.enabled = false
testClasses.enabled = false
再次执行build
之后就会发现这几个任务被跳过了:
如果只是忽略 test 相关的任务的话,在实际的生产中有一种更常用的方式,就是在build
指令后面加上 -x test
,这种方式会将 test 相关的任务直接从 build
的生命周期中移除。
4.总结
本篇主要是在讲解 Task 的基础知识以及如何使用Task,要点如下:
- 认识 Task 是 gradle 的基本组成单元,讲述了如何找到可以执行的 Task。
- 认识 Task 的两种类型:生命周期任务和可执行任务
- 认识如何使用 Task:通过 gradlew 指令或者 IDEA 右侧的 gradle 面板
- 认识Task执行结果的含义:增量任务、缓存任务的联系和区别,如果跳过任务
如果还想了解如何在项目中编写自己的 Task 以及如何对原有的 Task 进行拓展,可以关注我后续的文中。
标签:Task,含义,Gradle,任务,构建,build,执行 From: https://blog.csdn.net/qq_38249409/article/details/140181475