Gradle 7.0+ 中 dependencyResolutionManagement 的 alias 仅为仓库内部标识,不改变依赖解析逻辑;implementation 不支持 from 语法,依赖来源由仓库 URL、缓存状态及子项目是否显式声明 repositories 共同决定,而非别名。

build.gradle里改了dependencyResolutionManagement别名,但模块还是找不到
Gradle 7.0+ 引入 dependencyResolutionManagement 块统一管理仓库和版本,很多人在 settings.gradle.kts 或 settings.gradle 里给仓库起了别名(比如 aliyun),然后在 build.gradle 里写 implementation 'com.example:lib:1.0' from 'aliyun' —— 这种写法根本不会生效,Gradle 不支持在 implementation 后加 from 关键字。
别名只是给仓库起个内部代号,不改变依赖解析逻辑;Gradle 解析依赖时只认 repositories 块的声明顺序和匹配能力,不会根据你写的“别名”去定向拉取。
- 别名只在
dependencyResolutionManagement { repositories { maven { name = "aliyun" } } }中定义有效,对外不可见 -
implementation、api等配置项不接受from、via、using等路由参数 - 真正控制来源的是仓库 URL 是否包含所需坐标,以及
metadataSources是否启用 POM/JAR 优先策略
为什么alias写对了,./gradlew dependencies却显示来自mavenCentral
即使你在 dependencyResolutionManagement 中把阿里云镜像放在最前面,./gradlew dependencies 仍可能显示某个依赖“Resolved from: Maven Central”。这不是 bug,而是 Gradle 的元数据缓存行为:它会复用本地已有的 .module 文件(含校验和与来源记录),只要缓存没过期、POM 内容一致,就不会重新请求远程仓库。
换句话说,Gradle 不是每次构建都“重走一遍网络链路”,而是优先查本地缓存,再比对远程 checksum。如果你之前从 mavenCentral() 下过这个依赖,哪怕现在配置了更快的镜像,它也懒得换源。
- 验证方式:
ls -l ~/.gradle/caches/modules-2/files-2.1/com.example/lib/1.0/,看里面是否有lib-1.0.pom和对应.module文件 - 强制刷新:加
--refresh-dependencies参数,或删掉该路径下整个版本目录 - 更彻底:删
~/.gradle/caches/modules-2/metadata-2.96(Gradle 8.4+)让元数据重建
settings.gradle.kts中alias被识别,但子项目build.gradle里repositories为空
这是最常见的误解:dependencyResolutionManagement 块定义的仓库是全局生效的,但它**不自动注入到每个子项目的 repositories 块中**。如果子项目 build.gradle 显式写了 repositories { mavenCentral() },或者压根没写 repositories 块,那 Gradle 就不会合并 settings 里的配置——它只在没有显式声明时才 fallback 到全局配置。
尤其注意 Kotlin DSL 子项目:如果用了 plugins { id("com.android.application") } 这类插件,Android Gradle Plugin 会自动添加自己的仓库(如 google()),覆盖或干扰你设的别名逻辑。
- 检查子项目是否写了空的
repositories {}块(这会清空所有默认源) - 确认没在子项目里调用
repositories.removeAll()或类似操作 - Android 项目要留意
android.useAndroidX=true和 AGP 版本对仓库自动注入的影响(AGP 8.2+ 默认加google())
alias改名后CI构建失败,但本地能过
CI 环境通常禁用 Gradle 守护进程、清理缓存、使用干净 workspace,所以它比本地更“诚实”地反映真实配置问题。如果你改了 alias 名称(比如从 "maven-aliyun" 改成 "aliyun-mirror"),但 CI 脚本里还残留旧的调试日志、条件判断或自定义插件逻辑(例如某插件通过 project.repositories.findByName("maven-aliyun") 获取仓库),就会直接 NPE 或跳过关键步骤。
别名不是“开关”,它是纯标识符;一旦其他代码硬编码引用它,改名就等于断链。
- 全局搜索项目中所有
"maven-aliyun"、findByName、withName调用点 - CI 构建日志里搜
No such property: repositories for class或Cannot find repository with name - 避免在插件或脚本中依赖别名做逻辑分支,改用 URL 字符串匹配更可靠
别名本身不参与依赖解析路径,它的作用仅限于日志可读性和调试定位。真正决定“从哪下载”的,是仓库 URL 的可达性、POM 元数据完整性、本地缓存状态,以及子项目是否无意中屏蔽了全局配置。最容易被忽略的,是以为改了 alias 就等于“切换了源”,结果调试半天才发现问题出在缓存没清、子项目覆盖了配置、或者 CI 脚本里藏着一行硬编码。











