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
方法二:手动安装
- 去 https://gradle.org/releases/ 下载 Binary-only 包。
- 解压到某个路径,比如
/opt/gradle。 - 配置环境变量
GRADLE_HOME并加入PATH。
~/.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。
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 的构建流程是怎么运转的。
实战:建一个最简单的单模块项目
光说不练假把式。我们创建一个最简单的 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() }:配置了
testTask 的具体行为。
第三步,执行构建:
gradle build
你会看到 Gradle 依次执行 compileJava、processResources、classes、compileTestJava、test、jar 等 Task。整个过程就是 Project 驱动 Plugin,Plugin 调度 Task 来完成的。