Gradle 构建入门:Groovy DSL 与 Task

FreeGuideOnline 最新 2026-06-17

Gradle 构建入门:Groovy DSL 与 Task

Gradle 是当前 Java 生态中最流行的构建工具之一,它以 Groovy 或 Kotlin 作为领域特定语言(DSL),用灵活的任务模型统一了构建逻辑。本篇教程将从零开始,带你理解 Gradle 的核心概念——Groovy DSL 的书写方式以及 Task 的基本用法,让你能够快速上手并维护自己的构建脚本。

1. 认识 Gradle 与 Groovy DSL

Gradle 本身的构建文件是一段脚本,默认使用 Groovy DSL(也可以选择 Kotlin DSL)。这意味着你可以直接在构建脚本中使用 Groovy 的语法、变量和控制流,而 Gradle 则将这些脚本翻译为一系列“任务(Task)”。

1.1 为什么选择 Groovy DSL 入门?

  • 简洁明了:写法接近自然语言,易于阅读和书写。
  • 动态特性:可以灵活定义变量、逻辑,适合中小项目快速配置。
  • 文档丰富:历史积累的示例绝大多数基于 Groovy DSL。

在项目根目录的 build.gradle 文件中,我们就可以开始编写构建逻辑。

// 一个最简单的 build.gradle
task hello {
    doLast {
        println 'Hello, Gradle!'
    }
}

2. Gradle 核心概念:项目与任务

Gradle 构建基于两个核心概念:

  • 项目 (Project):代表一个被构建的单元,可以是一个 jar 包、一个 web 应用等。每个 build.gradle 对应一个项目。
  • 任务 (Task):一个工作单元,例如编译 Java 源代码、打包、运行测试等。

所有构建逻辑都由 Task 组织。执行 gradle hello 时,Gradle 就会运行我们定义的 hello 任务。

3. 深入 Task:定义、配置与执行

3.1 创建 Task 的多种方法

Groovy DSL 提供了几种等效的 Task 定义方式:

// 方式1:使用 task 关键字 + 任务名
task myTask {
    doLast {
        println '执行 myTask'
    }
}

// 方式2:使用 create 方法
tasks.create('myTask2') {
    doLast {
        println '执行 myTask2'
    }
}

// 方式3:通过 TaskContainer 注册(惰性创建)
tasks.register('myTask3') {
    doLast {
        println '执行 myTask3'
    }
}

推荐使用 tasks.register:它属于 Gradle 的“惰性配置”,只有 Task 真正需要运行时才会被创建,可以优化构建性能。

3.2 Task 的配置块和执行块

一个 Task 脚本块内包含两种代码区域:

  • 配置阶段执行的代码:直接写在 Task 闭包内部(但不属于 doFirst/doLast)的语句,在配置阶段就会执行。
  • 执行阶段代码:写在 doLastdoFirst 内的语句,只有当该 Task 实际运行时才执行。

多看一个例子,有助于理解阶段差异:

task configureAndRun {
    // 这部分在配置阶段运行,无论该Task是否被调用
    println '正在配置 configureAndRun'

    doLast {
        // 这部分仅在任务执行时运行
        println '执行 configureAndRun 的 doLast'
    }
}

执行 gradle configureAndRun 输出:

正在配置 configureAndRun
执行 configureAndRun 的 doLast

如果仅仅执行 gradle tasks(列出所有任务),会发现“正在配置 configureAndRun”仍会打印,但 doLast 不会被执行。所以耗时的、依赖外部环境的操作一定要放在 doLast/doFirst 中,避免影响不必要的配置阶段。

3.3 doFirstdoLast

  • doLast:在当前 Task 的主要动作执行完毕后追加操作。
  • doFirst:在主要动作执行之前添加操作。

如果你没有给 Task 指定主要动作(即没有使用 doLast<<),则该 Task 的行为全由你添加的 doFirst/doLast 组成。

task orderDemo {
    doFirst {
        println '第一步'
    }
    doLast {
        println '第三步'
    }
    doLast {
        println '第四步'
    }
}
orderDemo.doFirst {
    println '真正第一步'
}
// 最终执行顺序:真正第一步 → 第一步(doFirst)→ ?(无主操作)→ 第三步 → 第四步

3.4 设置 Task 的依赖

使用 dependsOn 可以让某个 Task 依赖另一个 Task,只有所依赖的 Task 执行完毕或执行后,当前 Task 才会执行。

task cleanTemp {
    doLast {
        println '清理临时文件'
    }
}

task buildApp {
    dependsOn cleanTemp
    doLast {
        println '编译应用'
    }
}

运行 gradle buildApp 时,会先执行 cleanTemp,再执行 buildApp。也可以依赖多个任务:dependsOn cleanTemp, anotherTask

4. Groovy DSL 在构建中的常用模式

Gradle 的 Groovy DSL 不仅用于定义任务,更常用于配置插件(plugins)、依赖管理、属性设置等。掌握以下基本模式,能让你读懂 80% 的构建脚本。

4.1 变量与闭包

// 定义变量
def appName = 'MyApp'
version = '1.0.0'

task printInfo {
    doLast {
        println "项目: $appName, 版本: $version"
    }
}

$变量${表达式} 可以在双引号字符串内进行插值处理。

4.2 遍历与集合操作

// 定义一个文件列表
def configFiles = ['application.yml', 'db.properties']

task copyConfig {
    doLast {
        configFiles.each { file ->
            println "复制配置文件: $file"
        }
    }
}

Groovy 的闭包和集合操作让批量任务处理变得非常简洁。

4.3 扩展属性 (ext)

通过 ext 块可以在项目级别扩展属性,方便统一管理版本号等:

ext {
    springBootVersion = '3.1.5'
    javaVersion = JavaVersion.VERSION_17
}

task showExt {
    doLast {
        println "Spring Boot: ${springBootVersion}"
        println "Java: $javaVersion"
    }
}

5. 实战:编写一个简单的批量文件处理 Task

下面我们利用 Groovy 的文件操作能力和 Task 机制,编写一个实际可用的构建任务:将某个目录下的所有 .txt 文件复制到输出目录,并在文件名前加上时间戳。

task backupTextFiles {
    def sourceDir = file('config')
    def targetDir = file('build/backup')
    
    doLast {
        if (!sourceDir.exists()) {
            println "源目录不存在,跳过备份"
            return
        }
        targetDir.mkdirs()
        
        def timestamp = System.currentTimeMillis()
        sourceDir.eachFileMatch(~/.*\.txt/) { file ->
            def newName = "${timestamp}_${file.name}"
            def targetFile = new File(targetDir, newName)
            targetFile.text = file.text
            println "备份: ${file.name} -> ${newName}"
        }
    }
}

将需要处理的逻辑封装在 doLast 中,确保仅在执行阶段进行文件复制,避免配置阶段的副作用。

6. 总结与下一步

通过本篇,你已经掌握了 Gradle 的 Groovy DSL 基础和 Task 使用方法:

  • 构建脚本即 Groovy 代码:可在 build.gradle 中灵活编写逻辑。
  • Task 是构建原子单位:清楚区分配置阶段与执行阶段,合理使用 doLast/doFirst
  • 依赖管理:用 dependsOn 控制执行顺序。
  • 常用模式:变量、集合操作、ext 扩展属性使脚本更易读。

下一步建议

  1. 学习 Gradle 的常用内置插件,如 java 插件,理解它的 compileJavatest 等 Task 是如何组织的。
  2. 探索多项目构建(Multi-Project Build),掌握项目间依赖。
  3. 尝试将 Kotlin DSL (build.gradle.kts) 与 Groovy DSL 进行对比,迎接官方主推的静态类型 DSL 趋势。

Gradle 的灵活性远超传统 Maven,掌握其核心 DSL 与 Task 模型,将为你构建复杂工程打下坚实基础。