文章目录
- 安装下载
- [gradle wrapper](#gradle wrapper)
- 工具链配置
- Gradle各种配置文件
- gradle在IDEA配置
- 理解build.gradle配置原理
- 资源
安装下载
可以直接从腾讯云下载镜像下载

关于软件版本是一个非常有意思的事情,有兴趣可以看看:理解软件版本标识含义与版本号语义
从gradle的distribution可以看出来,更新非常快,基本上两周一个patch版本,两三个月一个minor版本,一年一个major版本。
- gradle-xxx-all.zip:包含源码、文档、示例代码、编译好的可执行文件
- gradle-xxx-bin.zip:只包含可执行文件
- gradle-xxx-src.zip:如果想要自己编译项目可以使用这个,all中只是源码文件,不是工程文件
一般现在bin版本就可以,不要选all,不然解压都要等很久。
下载好之后直接解压到指定目录就可以:

GRADLE_USER_HOME
首先,我们先来了解一下GRADLE_USER_HOME这个非常重要的目录:
GRADLE_USER_HOME默认在用户目录下的.gradle目录。
Windows:C:\Users\<user_name>\.gradle\
Linux:$HOME/.gradle
我们可以通过GRADLE_USER_HOME环境变量来自定义到指定的目录。

- .tmp:临时文件目录,存储构建过程中下载依赖、执行任务时的中间数据:临时jar包、插件解压文件等
- build-scan-data:Build Scan缓存数据,记录构建过程的性能、依赖等信息
- caches:全局缓存,本地仓库(本地缓存jar包)就在这个目录下,还有插件、构建任务中间缓存等
- daemon:Gradle 守护进程的日志和状态文件
- jdks:存储 Gradle 通过工具链(Toolchain) 自动下载的JDK
- kotlin-profile:Kotlin插件的配置、编译缓存
- native:存储平台相关的原生库(如 C/C++ 编译后的.so/.dll文件),适用于 NDK 或 Gradle Native 项目
- notifications:存储构建过程中的通知信息,如构建结果、警告的缓存
- workers:存储 Gradle 工作线程(Worker API)的元数据、临时文件(用于并行任务执行)
- wrapper:存储 Gradle Wrapper 自动下载的 Gradle 发行版(位于wrapper/dists目录下)
重点关注有3个:
- caches:Gradle的本地仓库就在caches\modules-2\files-2.1,为什么放在caches下,因为本地仓库其实就相当于本地缓存的jar包
- jdks:项目多了,每个项目可能依赖于不同版本的jdk,甚至是不同厂商的jdk,Gradle提供了插件,可以自动下载jdk,下载的jdk就放在这个目录
- wrapper:因为Gradle迭代非常快,不同的Major版本很多API不兼容,所以不同项目可能使用不同的Gradle版本,Gradle Wrapper自动下载的Gradle默认就在这个目录下
gradle wrapper

什么是Gradle Wrapper以及为什么需要它
因为gradle的升级非常快,所以不同的版本差异可能会很大,各种项目的版本都需要兼容,所以很难
不像maven,同一个项目(pom.xml)不同的人使用不同版本的maven基本不会有太大问题,如果遇到问题,基本往高版本升级基本不会有太大问题,比较maven现在major版本也才3。
但是gradle的major版本已经到9了,major版本不需要做向下兼容,所以升级major版本的时候一定要小心。
就算是相同的major版本,gradle项目,同一个项目,相同build.gradle配置文件,使用不同的版本很可能会出问题。
例如:
txt
Build file 'E:\app\me\gradle\learn-gradle\build.gradle' line: 3
An exception occurred applying plugin request [id: 'org.springframework.boot', version: '4.0.0']
> Failed to apply plugin 'org.springframework.boot'.
> Spring Boot plugin requires Gradle 8.x (8.14 or later) or 9.x. The current version is Gradle 8.5
所以,通常在gradle项目中会使用一个gradle wrapper的东西,主要就是为项目指定gradle版本,这样当其他人拿到相同的项目去执行构建的时候,就自动去下载对应版本的gradle。
通过gradle wrapper的方式,开发就不用自己去下载管理各种不同的Gradle版本了。
Gradle Wrapper配置(gradle-wrapper.properties)
gradle-wrapper.jar非常小只有几十KB,主要是用来下载gradle的。
如果项目已经使用了gradle-wrapper,那也可以通过配置gradle-wrapper.properties来修改为本地gradle。
gradle-wrapper.properties
properties
# 可以直接使用url,默认的就是从官方下载,网络好的,直接用默认的就行
# distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip
# 可以配置腾讯云的镜像地址
# distributionUrl=https://mirrors.cloud.tencent.com/gradle/gradle-9.2.1-bin.zip
# 也可以下载到本地,配置为本地地址,注意是zip文件,不是目录,Gradle会自动拷贝解压这个文件
distributionUrl=file:///D:/ptool/gradle/gradle-9.2.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
# 下载的解压的Gradle放到什么地方
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
# 下载的Gradle zip文件放在什么地方
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

wrapper工具的主类是GradleWrapperMain,gradle_user_home查找逻辑在GradleUserHomeLookup,具体实现在wrapper子项目中的PathAssembler类。
网速不好就尽量用本地安装包吧,它没有端点续传的功能,每次出现Read timed out之类的错误,都得从头开始下载。
gradlew脚本命令
gradle与gradlew的关系:有点像npm和pnpm,gradlew是gradle的包装,主要是处理了路径问题,使用指定版本的gradle而已。
在项目中,基本我们都会使用wrapper模式,通常我们使用的命令是gradlew,而不是gradle,因为gradle通常是全局统一配置的gradle,gradlew是项目的gradle。
下面的命令是gradlew的基本命令,如果没有使用wrapper,替换为gradle就可以。
基本命令
sh
# 查看本地 Gradle 安装版本
gradlew -v
gradlew --version
# 启动守护进程
gradlew --daemon
# 禁用守护进程运行任务
gradlew --no-daemon
# 停止所有守护进程
gradlew --stop
任务
sh
# 查看基础任务
gradlew tasks
# 查看所有任务(包括子项目和隐藏任务)
gradlew tasks --all
gradlew help --task <任务名>
# 查看 build 任务的详情
gradlew help --task build
gradlew help --task assemble
# 编译Java代码
gradlew compileJava
# 仅运行测试和校验:执行代码检查Checkstyle、单元测试、集成测试等校验任务,不打包
gradlew check
# 删除项目的build目录:构建产物、编译缓存等
gradlew clean

依赖*
依赖非常重要,我们需要解决的绝大多数问题都是依赖问题。
所以在看依赖命令之前,我们先来简单的解释一下依赖:
- implementation:编译和运行都需要
- api:主要用于库或者框架项目
- runtimeOnly:编译时需要,如JDBC驱动、日志实现(如logback-classic,编译时只需要日志接口slf4j-api,运行时才需要实现)
- testImplementation:测试代码编译 + 运行阶段,如JUnit
- testRuntimeOnly:测试运行时
api我们使用的比较少,但是在开源项目和框架中,我们能大量看到它的身影。
api和implementation最大的不同是,api具有传递性。
什么意思呢?
举个例子,我有一个库项目A:
groovy
dependencies {
api 'com.alibaba:fastjson:2.0.42'
implementation 'com.google.guava:guava:32.1.3-jre'
}
现在有一个项目B,依赖了A:B->A:
B项目是可以直接使用com.alibaba:fastjson:2.0.42,不需要单独在B项目中引入fastjson。
但是B项目如果要使用com.google.guava:guava:32.1.3-jre,就必须在项目中单独在引入guava。
如果B项目没有在B项目中引入guava,而使用了它,就会出现Class Not Found错误。
什么时候使用api呢?库、框架暴露的接口中包含了依赖的库,例如接口中返回值或者参数使用了JSON,这样依赖的库肯定也需要fastjson,这样就可以使用api。
sh
# 查看所有依赖
gradlew dependencies
# 查看指定配置的依赖(推荐,缩小范围)
gradlew dependencies --configuration <配置名>
# 查看指定期依赖(compileClasspath、runtimeClasspath)
gradlew dependencies --configuration compileClasspath
# 查看运行时依赖
gradlew dependencies --configuration runtimeClasspath
# 子项目可以加:子项目名称作为前缀
gradlew :app:dependencies --configuration runtimeClasspath
gradlew dependencyInsight --dependency <依赖名> --configuration <配置名>
# 查看 guava 依赖的详细信息(版本、来源、冲突解决)
# 配置名:compileClasspath、runtimeClasspath、implementation、testCompileClasspath、testRuntimeClasspath、testImplementation
gradlew dependencyInsight --dependency guava --configuration implementation
gradlew :app:dependencyInsight --dependency guava --configuration compileClasspath
# 锁定依赖版本
gradlew dependencies --write-locks

我们可以看到相关内容还是非常详细的。
Gradle默认处理依赖冲突的策略是:选择最高版本,所以,我们看到最终选择了更好版本的guava包。
当然可以指定强制版本:
groovy
configurations {
compileClasspath {
resolutionStrategy {
force 'com.google.guava:guava:33.4.6-jre'
}
}
}
也可以排除依赖:
groovy
dependencies {
implementation('com.google.guava:guava:33.5.0-jre') {
exclude group: 'com.google.guava', module: 'listenablefuture'
}
}
--write-locks是个什么东西呢?因为Gradle支持类似npm的动态版本,不过简化一些:
groovy
dependencies {
// 1. 通配符:匹配 2.15.x 系列的最新版本
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.+'
// 2. 区间范围:匹配 1.0.0 到 2.0.0 之间的最新版本(左闭右开)
implementation 'org.apache.commons:commons-lang3:[1.0.0, 2.0.0)'
// 3. 关键字:匹配最新正式版(不推荐)
implementation 'com.google.guava:guava:latest.release'
}
有动态版本,自然需要像npm的lock文件,解决不同人拉的库是相同的版本。
为什么需要动态版本呢?
因为我们通常需要自动去依赖patch版本,就是做了bug修复的版本,特别是一些重大漏洞。
但是我们很少随时去关注依赖的包做了哪些更新,复杂的项目依赖成千上万的包,要了解每个依赖包的更新,那啥事都别干了。
怎么办呢?答案就是动态版本。
我们再开发的时候,就可以使用implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.+'这一的版本。
这样,jackson做了patch更新的时候,会修改他们的patch版本号,Gradle就会自动拉取最新的patch版本。
因为,如果jackson遵照规范,新patch版本肯定是API兼容的,所以,我们也不用担心会出现不兼容的情况。
这样,我们不用去随时关系jackson做了什么bug修复、漏洞修复,因为我们使用的是最新的patch版本。
关于软件版本可以参考:理解软件版本标识含义与版本号语义
测试
sh
# 运行所有测试
gradlew test
# 运行单个测试类
gradlew test --tests vip.oschool.MyTestClass
# 运行单个测试方法
gradlew test --tests vip.oschool.MyTestClass.myTestMethod
# 通配符匹配
gradlew test --tests "vip.oschool.*" # 匹配包下所有测试
gradlew test --tests "*MyTestClass*" # 匹配类名包含的测试
构建
sh
# 构建项目
gradlew build
# 先清理,再完整构建
gradlew clean build
# -x 表示排除指定任务
gradlew build -x test
# 刷新依赖
gradlew build --refresh-dependencies
gradlew build --parallel
# 手动更新锁定版本,有动态版本的时候
gradlew build --update-locks
# 离线模式,通常用于测试
gradlew build --offline
注意一下--refresh-dependencies参数,这个是去强制刷新snapshot版本和动态版本依赖,不是去删除所有依赖重新下载。
通常我们不会使用snapshot版本,很多公司也不会使用动态版本,所以--refresh-dependencies很多时候没有必要。
安装发布包
sh
# 将产物安装到本地 Maven 仓库
gradlew install
# 发布到仓库
gradlew publish
scan
构建扫描,全方位分析构建过程,并生成报告,会上传到Gradle云端,公司项目慎用。
sh
# 普通构建并生成扫描报告
gradlew build --scan
# 对指定子项目执行任务并生成扫描
gradlew :app:build --scan
# 依赖分析并生成扫描
gradlew :app:dependencies --scan
工具链配置
工具链主要用来指定JDK版本的,Gradle脚本中可以为不同的项目、插件、甚至任务指定不同的JDK版本。
不同版本怎么管理切换呢?
答案是:toolchain
groovy
// 自定义使用版本
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
vendor = JvmVendorSpec.AMAZON
}
}
常用的vendor:ADOPTIUM、AZUL、AMAZON、MICROSOFT
Gradle会自动探测JDK,顺序如下:
- 系统属性
- 环境变量 JAVA_HOME
- GRADLE_USER_HOME/.gradle/jdks/
- /usr/lib/jvm/
- C:\Program Files\Java\ (Windows)
sh
# 查看可用工具链
gradlew -q javaToolchains

自动下载JDK插件
注意Gradle插件分为两类:
- Settings 插件:仅作用于构建初始化阶段,必须在settings.gradle(.kts)中应用
- Project 插件:作用于具体项目,在build.gradle(.kts)中应用
例如我们自动下载JDK的插件,可以通过settings.gradle配置:
groovy
pluginManagement {
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0'
}
}
// 根据java.toolchain配置自动下载JDK
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention'
}
网速不行,自动下载基本就没不要,但是可以通过Gradle属性org.gradle.java.installations.paths指定本地位置。
实测,网速还是非常快啊,比很多时候自己下都快:

下载完有4个文件:

Gradle各种配置文件
Gradle属性配置文件(gradle.properties)
和SpringBoot一样可以指定application.properties一样,gradle也可以配置gradle.properties
有很多地方可以放,优先级从高到低;
- 命令行参数
- 项目根目录的gradle.properties(如果有子项目,子项目自己的优先级更高)
- GRADLE_USER_HOME目录(可-Dgradle.user.home修改)下gradle.properties(默认位置:用户目录/.gradle/gradle.properties)
- 环境变量(比较麻烦,通常使用比较少)
属性文件还是比较有用,例如我们自己的本地的JDK,怎么告诉Gradle呢,就可以通过org.gradle.java.installations.paths属性配置
又比如说,我们因为仓库需要使用代理,那么我们就可以通过属性文件配置。
因为这些不是项目配置,是我们自己比较个性化的配置,所以就可以单独建一个gradle.properties文件,放在GRADLE_USER_HOME目录下。
这样就不会影响项目的配置,并且我们本地的所有Gradle的项目都可以共享这些配置。
properties
org.gradle.java.installations.paths=D:/Env/JDK/openjdk16,D:/Env/JDK/openjdk17,D:/Env/JDK/openjdk19,D:/Env/JDK/openjdk21
systemProp.http.proxyHost=198.185.120.100
systemProp.http.proxyPort=7000
systemProp.http.proxyUser=tim
systemProp.http.proxyPassword=123456
systemProp.https.proxyHost=198.185.120.100
systemProp.https.proxyPort=7000
systemProp.https.proxyUser=tim
systemProp.https.proxyPassword=123456
# -Dorg.gradle.jvmargs=-Xmx2048m
# org.gradle.jvmargs=-Xmx512m
命令行的配置优先级最高,通常是某一次运行的特殊配置,比如:
sh
gradle -Dorg.gradle.java.installations.paths=D:/Env/JDK/openjdk17 -Pgradle.user.home=F:/custom/home
我们再build.gradle脚本中,可以通过类似下面的方式直接获取属性值:
groovy
println("test.gradle.c=" + project.getProperty("test.gradle.c"))
System.properties.each { key, value ->
if (key.startsWith('http.proxy') || key.startsWith('https.proxy')) {
println " $key = $value"
}
}
Gradle所有初始化脚本、构建脚本及其优先级
除了扩展名为.properties的属性文件,Gradle还有扩展名是.gradle构建脚本,最常见的就是项目根目录下的build.gradle文件。
除了项目下的build.gradle文件,Gradle有一些初始化脚本。
- 在命令行指定文件,例如:gradle --init-script F:/tmp/init.gradle -q taskName
- GRADLE_USER_HOME目录下的init.gradle文件
- GRADLE_USER_HOME目录下的init.d目录下的*.init.gradle(所有以.init.gradle结尾的文件)
- GRADLE_HOME目录下的init.d目录下的*.init.gradle(所有以.init.gradle结尾的文件)
注意:
- 如果使用的是kotlin,指的是包含.kts后缀的文件,例如:build.gradle.kts
- GRADLE_USER_HOME目录下文件名必须是:init.gradle,其子目录init.d下的只需要以.init.gradle结尾即可
- 通常我们使用GRADLE_USER_HOME,而不是GRADLE_HOME
初始化脚本,可以用来放我们自己的一些工具脚本。
例如前面我们放在properties属性文件中的org.gradle.java.installations.paths,也可以通过init.gradle初始化脚本来设置:
groovy
System.setProperty('org.gradle.java.installations.paths',
'E:/language/java/openjdk17,E:/language/java/openjdk21,E:/language/java/openjdk22,E:/language/java/openjdk23,E:/language/java/openjdk24,E:/language/java/openjdk25')
代理也可以:
groovy
System.properties.putAll([
'http.proxyHost': 'proxy.company.com',
'http.proxyPort': '8080',
'https.proxyHost': 'proxy.company.com',
'https.proxyPort': '8080',
])
统一的仓库管理,这样避免在每个项目中再单独去配置仓库地址。
groovy
allprojects {
buildscript {
repositories {
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
gradlePluginPortal()
}
}
repositories {
maven { url 'https://maven.aliyun.com/repository/public' }
mavenCentral()
}
}
建议:本地jDK、仓库地址、代理地址、插件仓库地址、jvm都统一配置,不然,每次导入项目的时候,都要去配置一遍。
最关键的问题是,想IDEA这些集成环境导入项目就自动开始下载了,如果没有提前配置好,就使用了默认的配置了。
gradle在IDEA配置
IDEA对Gradle的支持比较好,我们来简单说一下几个重要的问题:

创建项目选Gradle就可以:

也可以通过命令行初始化,按照步骤走就可以:
sh
gradle init
理解build.gradle配置原理
build.gradle配置文件其实是一个脚本文件,使用的是Groovy或者Kotlin语言。
只是Gradle相当于提供了很多工具,例如:build.gradle你就可以直接使用preoject等对象。
要想清楚Gradle配置的原理,只需要理解Groovy的闭包。
下面就是一个简单的示例,可以直接放在build.gradle文件中,刷新就能执行。
groovy
class ServerConfig {
String host
int port
List<String> plugins = []
def host(String host) { this.host = host }
def port(int port) { this.port = port }
def plugin(String plugin) { plugins << plugin }
}
class ConfigBuilder {
ServerConfig serverConfig = new ServerConfig()
def server(@DelegatesTo(ServerConfig) Closure closure) {
closure.delegate = serverConfig
// 执行闭包中的方法,闭包中没有的时候,先去查找闭包的delegate,这里就是serverConfig
closure.resolveStrategy = Closure.DELEGATE_FIRST
closure()
// Groovy默认最后一行是作为返回值,所以server方法返回了ServerConfig
serverConfig
}
}
// 创建ConfigBuilder对象,并调用server方法
// server后面的{}就是闭包,就是一个代码块,被编译为Closure传给server方法
// server中closure()就相当于调用{}代码块
// 因为代码块中没有 host方法,就调用代理serverConfig的host方法
def config = new ConfigBuilder().server {
// 调用host方法,闭包本身没有,先去查找闭包的delegate,就是ServerConfig的host方法
host "localhost"
// 同理,这里相当于调用ServerConfig的port方法
port 8080
plugin "security"
plugin "monitoring"
}
println config.host
println config.port
println config.plugins
不熟悉Groovy没有关系,如果你会Java,Groovy就非常简单,Groovy就是Java的增强、脚本化。
有兴趣可以看一下下面2篇文章你就能够快速上手Groovy: