最近用IDEA做项目的时候发现springboot的默认模板已经从maven改为了gradle,而本人此前的gradle环境仅在安卓开发中,对于springboot项目还是第一次用gradle
另一方面本人安装的gradle没有进行环境变量等其他额外设置,对于安卓开发也是重装系统后没有怎么做过,导致gradle下载依赖的时候出现问题
该方法同样解决了gradle下载缓慢导致下载超时从而同步失败的问题
问题现象
在同步或构建项目时,Gradle 报错无法解析依赖,关键错误信息如下:
text
Could not resolve org.springframework.boot:spring-boot-buildpack-platform:4.0.6.
> Could not GET 'https://repo.maven.apache.org/maven2/.../...pom'.
Received status code 403 from server: Forbidden
Could not resolve org.jetbrains.kotlin:kotlin-stdlib:2.2.21.
> Could not GET 'https://repo.maven.apache.org/maven2/.../...pom'.
Received status code 403 from server: Forbidden
错误同时出现在两个子项目中:
- Spring Boot 后端 (
src/api):无法下载 Spring Boot 相关依赖 - Android 应用 (
src/app):无法下载 Kotlin、Android Gradle Plugin 等依赖
原因分析
Gradle 默认依赖仓库是 Maven Central (repo.maven.apache.org)。在某些网络环境下(尤其是国内),直接访问 Maven Central 可能会遇到:
- DNS 污染或解析失败
- IP 被限流或封禁,返回 403/连接超时
- 国际出口带宽不稳定
由于 Gradle 本身没有内置镜像fallback机制,一旦默认仓库不可用,所有依赖解析都会失败,导致项目完全无法构建。
修复思路:Gradle init 脚本 + 阿里云镜像
Gradle 支持通过 Initialization Scripts(init scripts) 在构建开始前执行全局配置。init 脚本放在 Gradle 安装目录的 init.d/ 文件夹下,对所有使用该 Gradle 实例的项目生效。
踩坑:为什么直接用 allprojects 不行?
一开始可能会想到在 init 脚本中这样写:
gradle
allprojects {
repositories {
maven { url 'https://maven.aliyun.com/repository/public' }
}
}
但这在 Android 项目中会直接报错:
text
Build was configured to prefer settings repositories over project repositories
but repository 'maven' was added by initialization script
原因: Android 项目的 settings.gradle.kts 通常会启用 RepositoriesMode.FAIL_ON_PROJECT_REPOS:
kotlin
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
这个配置强制要求所有仓库必须在 settings 级别声明,禁止任何项目级(project-level)或外部注入的仓库。因此 allprojects.repositories 会被 Gradle 拦截并报错。
正确做法:beforeSettings 注入
Gradle 提供了 beforeSettings 钩子,它会在 settings.gradle / settings.gradle.kts 执行之前 触发。在这个阶段修改 dependencyResolutionManagement,既不会被判定为"项目级仓库注入",又能确保镜像地址排在仓库列表的最前面。
同时,对于没有显式定义 dependencyResolutionManagement 的 Spring Boot 项目 ,beforeSettings 中启用该功能后,Gradle 会自动忽略 build.gradle 里的 repositories { mavenCentral() },默认采用 PREFER_SETTINGS 模式,从而实现零代码改动的全局镜像覆盖。
修复步骤
1. 确认 Gradle 安装路径
例如本地 Gradle 安装在:
makefile
E:\Application\gradle
2. 创建 init 脚本
在 init.d 目录下创建 china-mirror.gradle:
csharp
E:\Application\gradle\init.d\china-mirror.gradle
写入以下内容:
gradle
beforeSettings { settings ->
settings.pluginManagement {
repositories {
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
maven { url 'https://maven.aliyun.com/repository/public' }
google()
gradlePluginPortal()
mavenCentral()
}
}
settings.dependencyResolutionManagement {
repositories {
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/google' }
google()
mavenCentral()
}
}
}
3. 配置 IDE 使用本地 Gradle(关键)
如果 IDE(IntelliJ IDEA / Android Studio)使用的是自带的 Bundled Gradle,那么上述 init 脚本不会生效。需要手动指定本地 Gradle:
- File → Settings → Build, Execution, Deployment → Build Tools → Gradle
- Gradle path : 选择
E:\Application\gradle - 或使用
Specified location并填入上述路径
4. 重新同步项目
bash
# 先停止 Gradle Daemon,确保新配置生效
./gradlew --stop
# 重新构建或同步
./gradlew build
在 IDE 中点击 Reload All Gradle Projects 即可。
原理详解
init.d 的执行时机
Gradle 构建生命周期:
- 读取
init.d/*.gradle - 执行 init 脚本中的
beforeSettings - 执行项目的
settings.gradle[.kts] - 执行 init 脚本中的
settingsEvaluated - 配置并执行各个项目的
build.gradle[.kts]
通过 beforeSettings 注入仓库,相当于在"项目知道自己要哪些仓库"之前就准备好了镜像地址,后续项目自己的配置只会追加到列表末尾。
仓库解析顺序
以 Android 项目为例,最终解析时的仓库顺序为:
https://maven.aliyun.com/repository/public(init 注入)https://maven.aliyun.com/repository/google(init 注入)google()(来自settings.gradle.kts)mavenCentral()(来自settings.gradle.kts)
Gradle 会按顺序尝试每个仓库,只要阿里云镜像中存在该依赖,就会直接下载,不会回退到 Maven Central,从而彻底规避 403 问题。
兼容性说明
| 项目类型 | beforeSettings 注入效果 |
|---|---|
Android (已有 dependencyResolutionManagement) |
镜像追加到已有仓库列表最前面 ,不触发 FAIL_ON_PROJECT_REPOS |
Spring Boot (无 dependencyResolutionManagement) |
init 脚本自动启用该功能,默认 PREFER_SETTINGS 模式,自动忽略 build.gradle 中的 mavenCentral() |
总结
| 方案 | 优点 | 缺点 |
|---|---|---|
修改每个项目的 build.gradle |
简单直接 | 工作量大,新模块容易遗漏 |
| 全局 init 脚本(本文方案) | 一次配置,所有项目生效;无需改动业务代码 | 需要确保 IDE 使用的是本地 Gradle |
通过 init.d + beforeSettings 的方式,可以在不修改任何项目源码的前提下,为 Spring Boot、Android 乃至所有 Gradle 项目统一注入国内镜像,是解决 Maven Central 403 问题的最干净方案。