libs.bundles 是 Gradle 8.0+ 中用于声明逻辑关联、版本需对齐的依赖组合的机制,非物理打包;在 libs.versions.toml 的 [bundles] 下用字符串数组引用已定义的 libraries 别名,如 okhttp = ["okhttp", "okhttp-logging", "okhttp-mock"]。

什么是 libs.bundles?
Gradle 8.0+(含 7.6+)支持在 libs.versions.toml 中定义 bundles,它不是“打包多个 JAR”,而是声明一组**逻辑上总是一起用、版本需对齐的依赖项组合**。比如 libs.bundles.okhttp 可以同时包含 okhttp、logging-interceptor 和 mockwebserver,避免漏加或版本错配。
怎么在 toml 文件里定义 bundle
在项目根目录 gradle/libs.versions.toml 中写:
[bundles] okhttp = ["okhttp", "okhttp-logging", "okhttp-mock"] retrofit2 = ["retrofit", "converter-gson", "adapter-rxjava3"]
注意:bundle 的 value 是字符串数组,每个元素对应你在 [libraries] 下定义的依赖别名(不是 Maven 坐标)。
你得先确保这些别名已正确定义,例如:
[libraries]
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version = "4.12.0" }
okhttp-logging = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" }
okhttp-mock = { group = "com.squareup.okhttp3", name = "mockwebserver", version.ref = "okhttp" }
retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version = "2.9.0" }
converter-gson = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "retrofit" }
adapter-rxjava3 = { group = "com.squareup.retrofit2", name = "adapter-rxjava3", version.ref = "retrofit" }
-
version.ref复用同一版本号,是 bundle 能保持一致的关键 - 别名命名不能含点(
.),否则 Gradle 解析失败;推荐用短横线(-)分隔 - bundle 名称本身不带版本,它只是“引用集合”
怎么在 build.gradle(.kts) 中使用 bundle
在模块的 build.gradle.kts(或 build.gradle)中直接写:
dependencies {
implementation(libs.bundles.okhttp)
implementation(libs.bundles.retrofit2)
}
Gradle 会自动展开成对应的所有依赖项,并正确处理传递依赖和版本冲突。
常见错误现象:
-
Cannot access 'libs.bundles.xxx': it is public/*package*/ in module→ 检查是否在settings.gradle启用了预览特性:enableFeaturePreview("VERSION_CATALOGS") - IDE 不提示 bundle 补全 → 确保用的是 Kotlin DSL(
.kts),且 Gradle 版本 ≥ 8.0;Groovy DSL 目前不支持自动补全 bundle - 编译报错 “Could not resolve …” → bundle 中某个依赖别名拼写错误,或对应
[libraries]条目缺失
bundle 和传统 multi-declaration 的区别在哪
有人会写 implementation("a:b:1.0", "c:d:2.0") 一次引入多个,但这只是语法糖,没有语义约束。而 libs.bundles.xxx 的核心价值在于:
- 版本强绑定:所有成员共享
version.ref,改一个就全改 - 复用性高:同一 bundle 可在多个 module、甚至多个项目中直接复用(通过 includeBuild 或发布 catalog 插件)
- 可读性强:看到
libs.bundles.spring-boot-web就知道这是 Web 开发标配栈,不用再猜一堆坐标 - IDE 支持好:KTS 下能跳转、能 hover 查看成员、能 rename 重构整个 bundle
真正容易被忽略的是:bundle 本身不解决依赖冲突,它只是“声明时聚合”。如果两个 bundle 引入了同一个库的不同版本,仍需靠 constraints 或 force 显式干预 —— 这一点和单独声明依赖完全一样。

















