Gradle 构建自动化系统详解

Gradle 是一款开源、通用、基于 JVM 的构建自动化工具(Build Automation Tool),也是 Android 官方指定的构建系统。它融合了 Ant 的灵活性与 Maven 的约定优于配置(Convention over Configuration),并以有向无环图(DAG)任务调度、增量构建(Incremental Build)与构建缓存(Build Cache)闻名,被广泛应用于 Java / Kotlin / C++ / Swift 等项目的编译、测试、打包与发布。

1. 概述

1.1 Gradle 是什么

Gradle 将一次构建(Build)建模为一棵「项目树 + 任务图」:项目(Project)是构建的基本单位,任务(Task)是真正执行的独立工作单元(编译、测试、打包、发布等)。构建脚本通过 Groovy DSL 或 Kotlin DSL 描述「如何构建」,Gradle 负责调度、缓存与并发执行。

核心特性:

1.2 一次构建的三阶段

Gradle 把一次构建拆成三个阶段(Build Phase),依次执行:

阶段英文做什么
初始化Initialization运行 init 脚本,评估 settings.gradle(.kts),创建 Settings 对象与所有 Project 对象
配置Configuration评估所有参与项目的 build.gradle(.kts),注册 Task、应用插件、声明依赖,构造任务图(Task Graph)
执行Execution按任务图顺序调度并执行选定的 Task,输出构建产物
PlantUML diagram
Gradle 三阶段构建总览
关键术语(中英文对照):

1.3 与 Maven / Ant 的核心差异

维度MavenGradle
构建脚本XML(POM),固定生命周期Groovy DSL / Kotlin DSL,声明式脚本,可编程
性能每次新 JVM常驻 Daemon + 增量构建 + 并行执行
灵活性低,约定固定高,Task/插件体系高度可定制
缓存依赖缓存为主依赖缓存 + 任务输出构建缓存

2. 行为图(系统"做什么")

2.1 用例图 — Gradle 用户交互全景

围绕「开发者」「CI/CD 流水线」「企业平台」三类参与者,Gradle 提供的典型用例:

PlantUML diagram
图 1:Gradle 用例图
专有名词解释:

2.2 活动图 — 三阶段构建生命周期

一次 ./gradlew <task> 从命令行到出产物,完整经过初始化 → 配置 → 执行三个阶段:

PlantUML diagram
图 2:Gradle 三阶段构建生命周期活动图

对应到构建脚本,阶段归属如下(Kotlin DSL 示例):

// settings.gradle.kts —— 初始化阶段
rootProject.name = "basic"
println("初始化阶段执行")

// build.gradle.kts —— 配置阶段与执行阶段
println("配置阶段执行")                                    // 配置阶段

tasks.register("test") {                                  // 配置阶段注册
    doLast { println("执行阶段才运行") }                  // 执行阶段动作
}

tasks.register("both") {
    println("配置阶段执行(在注册闭包里)")                // 配置阶段
    doFirst { println("执行阶段-最先") }                  // 执行阶段
    doLast  { println("执行阶段-最后") }                  // 执行阶段
}

2.3 状态机图 — Task 执行状态

每个 Task 在构建生命周期中经历「注册 → 配置 → 进入任务图 → 状态判定 → 执行」,最终落在一种结果状态上:

PlantUML diagram
图 3:Task 执行状态机图
专有名词解释(Task 结果状态):

2.4 序列图 — ./gradlew build 内部时序

从用户敲下命令到控制台出现 BUILD SUCCESSFUL,客户端(Client)、守护进程(Daemon)、执行引擎之间的完整交互:

PlantUML diagram
图 4:./gradlew build 内部序列图
专有名词解释:

3. 结构图(系统"由什么组成")

3.1 部署图 — 运行时拓扑

Gradle 的运行横跨「开发者工作站 / CI 服务器 / Gradle User Home / 远程仓库 / 远程构建缓存」五类节点:

PlantUML diagram
图 5:Gradle 运行时部署图
专有名词解释:

3.2 组件图 — 核心架构

从「运行时 / 核心引擎 / 对外 API / 缓存」四个层面拆解 Gradle 内部组件及其依赖:

PlantUML diagram
图 6:Gradle 核心架构组件图
专有名词解释:

3.3 包图 — 源码模块划分

Gradle 源码按职责划分为多个独立模块(Package / Module),上层依赖下层:

PlantUML diagram
图 7:Gradle 源码包/模块依赖图
专有名词解释:

3.4 类图 — 核心对象模型

构建脚本中接触到的核心对象(Gradle、Settings、Project、Task、Configuration 等)及其关系:

PlantUML diagram
图 8:Gradle 核心对象模型类图
专有名词解释:

4. 实战演示操作手册

本章从一个空目录开始,完整走一遍「初始化 → 编写脚本 → 依赖管理 → 多项目 → 缓存」的实战流程。

4.1 初始化项目

mkdir my-app && cd my-app
gradle init --type java-application --dsl kotlin --test-framework junit-jupiter

自动生成:

my-app/
├── settings.gradle.kts      # 设置文件:项目名、子项目列表
├── build.gradle.kts         # 根项目构建脚本
├── gradlew / gradlew.bat    # Wrapper 启动脚本
├── gradle/
│   ├── libs.versions.toml   # 版本目录(集中管理依赖版本)
│   └── wrapper/gradle-wrapper.{jar,properties}   # Wrapper 元数据
└── src/main/kotlin/...      # 源码
要点:推荐始终使用 ./gradlew 而非本机 gradle,gradle/wrapper/gradle-wrapper.properties 中的 distributionUrl 锁定了 Gradle 版本,团队与 CI 构建完全一致。

4.2 编写构建脚本

先看 settings.gradle.kts 与 build.gradle.kts 的职责分工(Kotlin DSL):

// settings.gradle.kts —— 初始化阶段执行
rootProject.name = "my-app"

// 声明子项目(多项目构建时)
// include(":lib", ":app")

// build.gradle.kts —— 配置阶段执行
plugins {
    application          // 应用插件:提供 run / installDist 等任务
    id("org.jetbrains.kotlin.jvm") version "2.0.0"
}

repositories {
    mavenCentral()       // 声明依赖仓库
}

dependencies {
    implementation("com.google.guava:guava:33.0.0-jre")
    testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
}

application {
    mainClass.set("org.example.MainKt")
}

tasks.test {
    useJUnitPlatform()   // 配置 test 任务使用 JUnit Platform
}

自定义一个 Task:

tasks.register("hello") {
    group = "custom"
    description = "打印问候语"
    doLast { println("Hello from Gradle!") }
}
// 运行:./gradlew hello

4.3 声明依赖

常用依赖配置(Configuration)及其作用域:

配置作用域是否传递给下游消费者
implementation仅本模块编译/运行需要否(推荐默认使用)
api本模块对外暴露的类型所需是(仅 java-library 插件)
compileOnly仅编译期需要否
runtimeOnly仅运行期需要否
testImplementation测试源码编译与运行否
annotationProcessor注解处理器否

查看依赖树:

./gradlew dependencies          # 查看所有配置的依赖
./gradlew :app:dependencies     # 查看指定子项目
./gradlew dependencyInsight --dependency guava   # 定位某依赖的解析来源

集中管理版本(Version Catalog,推荐大型项目):

// gradle/libs.versions.toml
[versions]
guava = "33.0.0-jre"

[libraries]
guava = { group = "com.google.guava", name = "guava", version.ref = "guava" }

// build.gradle.kts 中引用
dependencies { implementation(libs.guava) }

4.4 消费 Maven 构建的库

Gradle 能无缝使用以 Maven 作为构建工具产出的第三方库(如 Guava、Jackson、Spring 等)。本质是:Maven 负责"生产"发布物,Gradle 负责"消费",两者通过 Maven 仓库中的 GAV 坐标(groupId:artifactId:version)+ POM 元数据 解耦。

Maven 构建的库发布到 Maven 仓库(Maven Central、公司私服 Nexus/Artifactory、本机 ~/.m2),Gradle 在 repositories {} 声明仓库即可解析:

repositories {
    mavenCentral()                                          // 官方中央仓库
    maven { url = uri("https://repo.mycompany.com/maven") } // 公司私服
    mavenLocal()                                            // 本机 ~/.m2
}

解析过程:声明 implementation("com.google.guava:guava:33.0.0-jre") 后,Gradle 从仓库下载三样东西——JAR 字节码、POM 元数据(用来推导传递依赖)、以及可选的 .module(Gradle 模块元数据,存在时优先)。Gradle 解析 POM 中 Maven 库自己的 <dependencies>,递归构建依赖图,因此 Maven 库的传递依赖对 Gradle 完全透明。

与 Maven 的关键差异 —— 版本冲突策略:
MavenGradle(默认)
冲突规则最近优先(依赖树中路径最短者胜出)最高版本优先(版本号最大者胜出)
强制指定直接改坐标版本force、strictly、resolution rules

完整示例:消费一个 Maven 构建的库(Guava),并查看它带来的传递依赖与冲突解决结果。

// build.gradle.kts
plugins {
    application
}

repositories { mavenCentral() }          // 1. 声明 Maven 仓库

dependencies {
    implementation("com.google.guava:guava:33.0.0-jre")   // 2. 声明 GAV 坐标
    implementation("org.apache.commons:commons-lang3:3.14.0")
}
// 3. 查看依赖树 —— Gradle 读取 guava 的 POM 得到传递依赖
./gradlew dependencies --configuration runtimeClasspath

runtimeClasspath - Runtime classpath of source set 'main'.
+--- com.google.guava:guava:33.0.0-jre
|    +--- com.google.guava:failureaccess:1.0.1
|    +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|    +--- com.google.code.findbugs:jsr305:3.0.2
|    \--- org.checkerframework:checker-qual:3.33.0
\--- org.apache.commons:commons-lang3:3.14.0
// 4. 冲突排查:某库被两个 Maven 依赖同时引入不同版本,看最终选谁
./gradlew dependencyInsight --dependency guava

com.google.guava:guava:33.0.0-jre
  variant "compile" ...
  +--- org.example:lib-a:1.0 (requested 31.0-jre)
  +--- org.example:lib-b:2.0 (requested 32.1.3-jre)
       \--- compileClasspath
  → 最高版本优先:选 33.0.0-jre

若不想遵循「最高版本优先」,可用强制约束锁定版本:

dependencies {
    implementation("com.google.guava:guava") {
        version { strictly("31.0-jre") }    // 锁定为指定版本
    }
}

4.5 多项目构建

// settings.gradle.kts
rootProject.name = "my-project"
include(":lib", ":app")
my-project/
├── settings.gradle.kts
├── build.gradle.kts        # 根项目:可统一配置所有子项目
├── lib/build.gradle.kts    # 库模块
└── app/build.gradle.kts    # 应用模块,依赖 lib
// app/build.gradle.kts —— 依赖兄弟模块
dependencies { implementation(project(":lib")) }

// 常用命令
./gradlew :lib:build        # 只构建 lib
./gradlew :app:run          # 运行 app
./gradlew build             # 全量构建(根 + 所有子项目)
任务路径语法::module:task。根任务用 : 前缀(如 :build),子项目任务用 :lib:build。

4.6 增量构建与缓存

# 首次构建
./gradlew build

# 再次构建(无改动 → 全部 UP-TO-DATE,几乎瞬时)
./gradlew build

# 启用本地构建缓存(同一台机器复用跨分支/跨目录产物)
./gradlew build --build-cache

# 查看每次构建的任务状态明细
./gradlew build --console=plain

常见输出状态:EXECUTED(真正执行)、UP-TO-DATE(增量命中)、FROM-CACHE(缓存命中)、NO-SOURCE(无输入)、SKIPPED(条件不满足)。

# 诊断缓存不生效
./gradlew help --task build
./gradlew build --info          # 查看每个任务为何跳过/为何缓存未命中
./gradlew clean build           # 强制全量(仅诊断用,日常不推荐)

5. 参数指令速查手册

5.1 最常用命令

命令说明
./gradlew <task>运行指定任务及其依赖
./gradlew tasks列出所有可用任务
./gradlew build编译 + 测试 + 打包(完整构建)
./gradlew clean删除 build/ 产物目录
./gradlew check仅运行质量检查(test、lint 等)
./gradlew assemble仅打包(不运行测试)
./gradlew test运行单元测试
./gradlew run运行应用程序(application 插件)
./gradlew dependencies打印依赖树
./gradlew dependencyInsight --dependency <gav>定位依赖解析来源与版本
./gradlew wrapper --gradle-version 9.6.1升级/生成 Wrapper
./gradlew init交互式初始化项目

5.2 常用命令行参数(CLI Options)

参数说明
--console=plain | rich | verbose控制台输出格式(CI 常用 plain)
-x <task> / --exclude-task排除指定任务
-i / --info详细日志
-s / --stacktrace打印异常堆栈
--debug最高级别调试日志
--parallel / --max-workers=N并行执行 / 限制最大 worker 数
--build-cache / --no-build-cache启用 / 禁用构建缓存
--configuration-cache启用配置缓存
--continuous / -t持续构建,文件变更自动重跑
--daemon / --no-daemon使用 / 不使用后台守护进程
--status查看 Daemon 状态
--stop停止所有 Daemon
-P<name>=<value>传入 project 属性(脚本里 project.property 读取)
-D<name>=<value>传入系统属性(JVM system property)
-b / --build-file指定构建脚本文件
--offline离线模式,仅用本地缓存
--refresh-dependencies强制刷新依赖缓存
--write-verification-metadata生成依赖校验元数据(供应链安全)

5.3 gradle.properties 常用配置

属性说明
org.gradle.jvmargs=-Xmx2gDaemon JVM 内存参数
org.gradle.daemon=true启用 Daemon(默认 true)
org.gradle.parallel=true并行构建子项目
org.gradle.caching=true默认开启本地构建缓存
org.gradle.configuration-cache=true默认开启配置缓存
org.gradle.java.home=/path/to/jdk指定 Daemon 使用的 JDK
org.gradle.toolchain.foo=…toolchain 相关配置

5.4 Wrapper 速查

命令说明
./gradlew --version查看当前 Gradle / JVM 版本
./gradlew wrapper --gradle-version 9.6.1升级到指定版本
./gradlew wrapper --gradle-distribution-url <url>使用自定义分发包地址
./gradlew help查看帮助

5.5 常见问题快速排查

症状排查命令
构建很慢gradle --status 看 Daemon;--info 看卡在哪个 Task
缓存一直未命中./gradlew build --info 查看 UP-TO-DATE / FROM-CACHE 判断原因
依赖版本冲突./gradlew dependencyInsight --dependency <gav>
Daemon 内存溢出gradle --stop 后调大 org.gradle.jvmargs
多个 Gradle 版本共存始终使用 ./gradlew,靠 Wrapper 锁版本