Maven 仓库下载机制
本文覆盖:Mirror 与 Repository 的职责区别、
<mirrorOf>语法、国内仓库选择、两种典型配置场景。
1. 两个角色
Maven 下载依赖管线中有两个配置层:
| 配置层 | 位置 | 职责 |
|---|---|---|
| Mirror | MAVEN_HOME/conf/settings.xml |
替换仓库 URL(改道) |
| Repository | 项目 pom.xml |
追加下载源 |
关键区别:Mirror 不支持多源 fallback,Repository 支持。 这个区别是第 5、6 节选择配置方案的前提------如果不理解它,就会误以为配多个 Mirror 就能互相备用。
2. <mirrorOf> 语法
<mirrorOf> 的值是仓库 ID(不是镜像自己的名字),决定该镜像拦截哪些仓库。
| 值 | 效果 | 适用场景 |
|---|---|---|
central |
只拦截 Maven 内置仓库 | 日常加速(见第 5 节) |
* |
拦截所有仓库 | 全局代理 |
*,!xxx |
拦截所有,排除 xxx |
精准放行(见第 6 节写法 B) |
来源:Maven 官方 Settings 文档,
mirrorOf支持*、external:*、repo1,repo2、*,!repo1四种语法。
了解了语法之后,接下来看具体有哪些仓库可用。
3. 国内仓库一览
在决定用哪个仓库之前,先了解有哪些可选。
| 仓库 | 地址 |
|---|---|
| 阿里云 | https://maven.aliyun.com/repository/public |
| 华为云 | https://mirrors.huaweicloud.com/repository/maven/ |
| Maven 官服 | https://repo1.maven.org/maven2/ |
国内访问速度:阿里云与华为云均部署全国 CDN,下载速度远快于海外直连官服。两者分属不同云厂商,物理隔离,一个故障不会影响另一个。腾讯云 Maven 镜像维护频率较低,不建议作为主力。
推荐顺序:阿里云(首选)→ 华为云(备用)→ 官服(兜底)。 第 5、6 节将基于这个顺序给出两种场景的配置方案------但在此之前,第 4 节先解决一个关键前置问题。
4. * 和 central 的本质区别
在进入场景之前,先搞清楚最容易被忽视的一点:
以下对比表基于 Maven Mirror 机制推导,官方文档描述了
mirrorOf的匹配规则但未直接给出此表格。
| 设置 | pom 无仓库 | pom 有仓库 |
|---|---|---|
mirrorOf central |
正常 | pom 仓库能正常工作 |
mirrorOf * |
正常(和 central 没区别) |
pom 仓库被劫持,作废 |
不配 pom 仓库时,两者行为完全一致。区别只在 pom 加了仓库后才显现。
这个区别直接影响第 5、6 节两种场景的写法选择。
5. 需求一:只要一个源
不改 pom。settings 配一个 mirror,mirrorOf 设为 central:
xml
<!-- MAVEN_HOME/conf/settings.xml -->
<mirror>
<id>aliyunmaven</id>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
效果: Maven 内置 central 仓库被镜像拦截,所有请求改道阿里云。pom 无须改动。此时写 * 效果一样------因为没配 pom 仓库,第 4 节的对比表已经说明了这一点。
需求一的问题在于:一旦阿里云缺少某个依赖(如迟迟未同步的新版本),构建直接失败。需求二正是为了解决这个问题。
6. 需求二:一个源不够,需要兜底
当阿里云未同步某些新版本(如 sensitive-word 0.25.0),需要自动尝试其他源。
Mirror 层不支持 fallback------第一个匹配的 Mirror 失败后不会尝试下一个。因此多源 fallback 必须在 Repository 层实现。 本节提供两种写法。
写法 A(推荐):Mirror 只加速 central,Pom 加备用
回顾第 4 节对比表:mirrorOf central 不会劫持 pom 仓库,因此可以安全添加。
xml
<!-- MAVEN_HOME/conf/settings.xml -->
<mirror>
<id>aliyunmaven</id>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
<!-- 项目 pom.xml -->
<repositories>
<!-- ① 首选阿里云,已由 settings.xml mirror 加速,此处不重复声明 -->
<!-- ② 备用:华为云 -->
<repository>
<id>huawei</id>
<url>https://mirrors.huaweicloud.com/repository/maven/</url>
</repository>
<!-- ③ 兜底:Maven 官服 -->
<repository>
<id>official</id>
<url>https://repo1.maven.org/maven2/</url>
</repository>
</repositories>
流程: central 走阿里云 → 若 404 → 试 huawei → 若 404 → 试 official(官服,一定有)。
写法 B(严格):Mirror 全拦,只开一个洞
对应第 4 节对比表 mirrorOf *,!direct。适合"只信任阿里云,仅允许一个例外"的场景。
xml
<!-- MAVEN_HOME/conf/settings.xml -->
<mirror>
<id>aliyunmaven</id>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
<mirrorOf>*,!direct</mirrorOf>
</mirror>
<!-- 项目 pom.xml -->
<repositories>
<repository>
<id>direct</id> <!-- 与 !direct 对上 -->
<url>https://repo1.maven.org/maven2/</url>
</repository>
</repositories>
流程: 所有仓库被拦截到阿里云;唯独 direct 放行直连官服。
以上两种写法各有适用场景。大多数日常场景用写法 A 即可;缺的自动试华为云,都没有走官服。新依赖不需要逐个配置仓库。