配置缓存解决构建脚本解析和初始化阶段的重复开销,通过序列化配置图实现复用;构建缓存解决任务执行阶段的重复计算,基于输入快照哈希判断是否跳过任务。

配置缓存解决的是构建脚本解析和初始化阶段的重复开销
Gradle每次执行构建,都要加载settings.gradle、build.gradle(或.kts)等脚本,解析项目结构、插件、依赖、任务定义等。这个过程本身不编译代码,但可能耗时数秒甚至十几秒——尤其在多模块、大量插件或动态逻辑(如afterEvaluate)的项目中。
配置缓存把整个构建配置图(project hierarchy, task graph, plugin application order 等)序列化并缓存下来。下次构建时,只要脚本内容、Gradle版本、JVM参数等关键输入没变,就直接复用缓存的配置图,跳过脚本执行和DSL解析。
- 只对 Gradle 6.6+ 有效,且默认 不启用,需显式配置
org.gradle.configuration-cache=true - 要求所有构建脚本“纯函数化”:不能读取环境变量(除非声明为
providers.environmentVariable)、不能写文件、不能调用System.currentTimeMillis()等非确定性 API - 一旦启用失败,Gradle 会报类似
Configuration cache entry not found或列出具体不兼容的 DSL 调用位置
构建缓存解决的是任务执行阶段的重复计算
这是更常被使用的缓存机制,目标是避免重新运行已知输入不变的任务——比如JavaCompile、Test、ProcessResources等。它基于任务的输入快照(源码、classpath、参数、环境变量等)生成哈希键,将输出(class 文件、test reports、jar 包等)存入缓存。
它不关心脚本怎么写的,只关心“这次任务的输入和上次一模一样吗”。所以即使配置阶段每次都重跑,只要构建缓存命中,90% 的耗时任务仍可跳过。
- 从 Gradle 5.1 起默认开启,只需在
gradle.properties中设org.gradle.caching=true - 本地缓存自动生效;远程缓存需额外配置
org.gradle.cache.remote.url并确保 CI/CD 有 push 权限 - 自定义任务必须显式声明
inputs和outputs,否则 Gradle 无法判断是否可缓存(常见坑:Copy任务忘了设outputs.dir)
两者叠加使用才有最大收益,但失效条件完全不同
配置缓存失效通常源于构建脚本变更或 Gradle 升级;构建缓存失效更多来自源码修改、依赖版本浮动(如1.2.+)、操作系统差异(Windows/macOS 默认不共享缓存)、或未锁定环境变量(如未用 providers.systemProperty 声明)。
一个典型现象是:配置缓存命中率很高(>95%),但构建缓存命中率只有 30%——这说明脚本解析快了,但任务本身因输入不稳定反复重建。此时应优先检查依赖声明方式、自定义任务的输入完整性、以及团队环境一致性。
真正容易被忽略的是:配置缓存一旦启用,它会严格校验所有构建脚本的“确定性”,而构建缓存则对脚本写法宽容得多。换句话说,配置缓存是“高要求、高回报”,构建缓存是“低门槛、广覆盖”。











