Gradle 入门:从零开始认识构建工具

我记得自己刚接触 Java 项目时,用的还是 Ant 和 Maven。那时候觉得 Maven 的约定大于配置已经挺方便了,直到第一次接手一个真正多模块的微服务项目……嗯,Maven 的 XML 配置堆了上千行,看得我头皮发麻。后来团队决定迁移到 Gradle,说实话一开始我也犹豫过,但用了一个月就回不去了。

今天我们就从最基础的东西聊起。不讲复杂理论,只讲你马上能用上的。

Gradle 是什么?为什么我们需要它?

简单说,Gradle 是一个构建工具。但它不是 Maven 的替代品,我觉得更像是一次升级。你想想看,一个 Java 项目从编写代码到最终运行,中间要经历编译、测试、打包、部署。这些重复劳动如果全靠手动执行,不仅累,还容易出错。Gradle 就是用来自动化这些流程的。

我个人认为 Gradle 最大的两个特点是:

  • 基于 Groovy 或 Kotlin 的 DSL:配置就是代码,比 XML 灵活得多。你可以写逻辑、循环、条件判断。
  • 增量构建:只重新编译改动的文件。我当年在 Maven 里改一行代码需要等全量编译两分钟,切到 Gradle 后变成十秒。

除了 Java,它还支持 Kotlin、Android、C++ 等。不过我们这门课主要针对 Java 多模块 Mock 依赖管理,所以接下来会聚焦在 Java 生态上。

安装与配置:三分钟搞定

安装 Gradle 其实很简单。我习惯用 SDKMAN 来管理,省心。当然你也可以去官网下载二进制包手动解压。

方法一:SDKMAN(推荐)

# 安装 SDKMAN
curl -s "https://get.sdkman.io" | bash

# 安装 Gradle 最新版
sdk install gradle

# 验证
gradle --version

方法二:手动安装

  1. 去 https://gradle.org/releases/ 下载 Binary-only 包。
  2. 解压到某个路径,比如 /opt/gradle。
  3. 配置环境变量 GRADLE_HOME 并加入 PATH。

小提示:我个人喜欢把 Gradle 安装在 ~/.gradle 下面,这样和用户配置文件放在一起,方便备份。不过这个纯属个人习惯,怎么都行。

安装完成后可以验证一下:

$ gradle --version
------------------------------------------------------------
Gradle 8.6
Build time:   2024-03-29 14:51:00 UTC
Revision:     2e7d4e6ae7c6c5b6c7a0a1b2c3d4e5f6a7b8c9d0
Kotlin:       1.9.22
Groovy:       3.0.17
Ant:          Apache Ant 1.10.13
JVM:          17.0.10 (Oracle Corporation 17.0.10+11)
OS:           Linux 6.5.0-14-generic amd64

看到这个信息就说明安装成功了。注意检查 Java 版本,Gradle 8.x 需要 JDK 17 以上。我建议直接用 JDK 17 或 21,别用太老的版本,否则有些插件会报错。

基本概念:Project、Task、Plugin

这三个是 Gradle 最核心的抽象。理解了它们,后面几乎所有操作都是围绕它们展开的。

1. Project —— 你的项目

每个 build.gradle 文件对应一个 Project。在多模块项目中,根目录有一个 Project,每个子模块又是一个独立的 Project。你可以把 Project 想象成一个「容器」,里面装了源代码、资源文件、依赖配置、任务定义等等。

我曾经犯过一个错:在根项目的 build.gradle 里给所有子模块统一配置了一个专属于 API 模块的插件,结果导致非 API 模块编译失败。所以记住:Project 是隔离的,但可以通过 allprojects 或 subprojects 统一配置。

2. Task —— 具体的构建动作

Task 就是你要执行的一个原子操作。比如编译、运行测试、打 jar 包,都是一个个 Task。Gradle 内置了很多常用 Task,比如 compileJava、test、jar。你也可以自定义 Task。

举个例子,如果你想在构建前打印一条消息:

tasks.register('hello') {
    doLast {
        println 'Hello from Gradle!'
    }
}

执行 gradle hello 就能看到输出。Task 之间还有依赖关系,比如 build Task 依赖 test,test 又依赖 compileJava。你只管执行 gradle build,Gradle 会自动按顺序执行所有依赖的 Task。

重要:Task 的配置阶段和执行阶段是分开的。很多新手在配置阶段直接写 println 会发现输出时机不对。记住:doFirst 和 doLast 里的代码才在 Task 执行阶段运行。

3. Plugin —— 功能扩展包

Plugin 就是一堆 Task 和配置的集合。比如你引入 java 插件,它就自动帮你定义了 compileJava、test、jar 等 Task 以及默认的源文件目录结构。

Gradle 有两种插件:

  • 脚本插件:从其他文件引入的 apply from: 'some.gradle'。
  • 二进制插件:通过 ID 或类名应用,比如 plugins { id 'java' }。我更推荐用二进制插件,因为它们有版本管理,更规范。

避坑指南:我曾经在项目里同时用了 plugins { } 块和 apply plugin: 老写法,结果导致插件重复加载,Task 定义了两遍,排查了半小时。所以建议统一只用 plugins { } 块,从 Gradle 4.0 开始这就是推荐方式。

它们之间的关系:一张图说清楚

下面这张图把 Project、Task、Plugin 以及它们之间的依赖关系画出来了。你看一眼就能理解 Gradle 的构建流程是怎么运转的。

Gradle 核心概念与构建流程 Root Project 子模块A (Project) 子模块B (Project) 子模块C (Project) Plugin(插件) java 插件 maven-publish 插件 自定义插件 Task(任务) compileJava test jar customTask 每个 Project 可以应用多个 Plugin,每个 Plugin 提供一组 Task。 Task 之间有依赖关系(虚线箭头),Gradle 自动按序执行。 compileJava 依赖 --> 依赖 依赖

实战:建一个最简单的单模块项目

光说不练假把式。我们创建一个最简单的 Java 项目,感受一下这三个概念是如何协同工作的。

第一步,创建项目目录并初始化:

mkdir my-first-gradle && cd my-first-gradle
gradle init --type java-application --dsl groovy --test-framework junit-jupiter

运行后 Gradle 会生成 build.gradle、settings.gradle、源代码目录等。

第二步,打开 build.gradle,你会看到类似这样的内容:

plugins {
    id 'java'
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
}

test {
    useJUnitPlatform()
}

这里出现了三个要素:

  • plugins:引入了 java 插件,它自动添加了 compileJava、test、jar 等 Task。
  • repositories & dependencies:属于 Project 的配置,告诉 Gradle 去哪里下载依赖。
  • test { useJUnitPlatform() }:配置了 test Task 的具体行为。

第三步,执行构建:

gradle build

你会看到 Gradle 依次执行 compileJava、processResources、classes、compileTestJava、test、jar 等 Task。整个过程就是 Project 驱动 Plugin,Plugin 调度 Task 来完成的。

核心总结:Project 是组织单位,Plugin 是能力包,Task 是执行单元。这三者的关系就是 Gradle 的骨架。后面所有章节,包括多模块 Mock 依赖管理,都是在这个骨架上搭起来的。