Maven查找Jar包全过程

Maven依赖解析本质是一个分层仓库查找 + 元数据驱动 + 传递依赖解析的过程。从工程化角度看,本质类似“多级缓存 + 依赖图解析”。


1.查找顺序(核心路径)

1.1 本地仓库优先(Local Repository)

默认路径:

1
~/.m2/repository

查找规则:

1
${groupId路径}/${artifactId}/${version}/${artifactId}-${version}.jar

示例:

1
2
org.springframework:spring-core:5.3.30
→ ~/.m2/repository/org/springframework/spring-core/5.3.30/spring-core-5.3.30.jar

结论:

  • 本地存在 → 直接使用(命中缓存)
  • 不存在 → 进入远程解析流程

1.2 远程仓库查找(Remote Repository)

Maven按顺序查找:

  1. 项目 pom.xml<repositories>
  2. 用户级 ~/.m2/settings.xml
  3. 全局 settings.xml
  4. 默认中央仓库:Maven Central Repository

2.远程解析流程

2.1 先下载metadata(核心)

Maven不会直接下载jar,而是:

1
2
3
1. 请求 maven-metadata.xml
2. 判断版本
3. 决定下载哪个 artifact

metadata 示例:

1
2
3
4
5
6
7
8
9
10
<metadata>
<versioning>
<latest>1.3.0</latest>
<release>1.2.5</release>
<versions>
<version>1.0</version>
<version>1.1</version>
</versions>
</versioning>
</metadata>

用于:

  • 解析 LATEST
  • 解析 RELEASE
  • SNAPSHOT 版本定位

2.2 SNAPSHOT版本解析机制(重点)

1
2
3
1. 请求 metadata
2. 获取 timestamp + buildNumber
3. 下载真实文件

示例:

1
2
1.0-SNAPSHOT
→ 1.0-20260328.123456-3.jar

本质:

  • SNAPSHOT = 动态版本
  • 每次构建可能变化

2.3 下载Jar + 校验

下载内容:

1
2
3
.jar
.pom
.sha1 / .md5

校验流程:

1
下载 → 校验hash → 写入本地仓库

3.依赖传递解析(Dependency Graph)

Maven不是只下载你声明的jar,而是递归解析依赖树

graph TD
A[你的项目] --> B[spring-core]
B --> C[spring-jcl]
B --> D[commons-logging]

3.1深度优先 + 最近优先

冲突策略:

1
2
3
1. 距离最近优先
2. 路径短优先
3. 声明优先(dependencyManagement)

3.2 版本冲突示例

1
2
A → B → C:1.0
A → D → C:2.0

Maven选择:

1
谁路径短 → 用谁

4.仓库查找优化机制

4.1 本地缓存(核心优化)

1
~/.m2/repository

特点:

  • 永久缓存
  • 避免重复下载
  • 支持离线构建

4.2 镜像仓库(Mirror)

如阿里云镜像:

1
2
3
4
5
<mirror>
<id>aliyun</id>
<mirrorOf>*</mirrorOf>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>

本质:

  • 替换远程仓库入口
  • 加速下载

4.3 私服(Nexus / Artifactory)

常见:

  • Sonatype Nexus Repository Manager
  • JFrog Artifactory

作用:

1
开发 → 私服 → 外网仓库

企业级架构:

graph LR
Dev[开发机器] --> Nexus[私服]
Nexus --> Central[Central Repo]

5.完整流程

1
2
3
4
5
6
7
8
9
10
1. 解析pom.xml依赖
2. 查本地仓库 (~/.m2)
3. 未命中 → 查远程仓库
4. 下载 metadata
5. 确定版本(尤其 SNAPSHOT)
6. 下载 jar + pom + 校验文件
7. 写入本地仓库
8. 递归解析传递依赖
9. 解决版本冲突
10. 构建完整依赖树

6.生产常见问题

6.1 依赖下载失败

1
2
3
4
原因:
- 网络问题
- 仓库配置错误
- SSL问题

6.2 依赖冲突(经典)

1
mvn dependency:tree

6.3 SNAPSHOT污染

1
2
3
4
问题:构建不稳定
解决:
- 禁用SNAPSHOT
- 使用 release 仓库

7.总结

Maven查jar本质:

本地缓存优先 + 元数据驱动版本解析 + 递归依赖图构建 + 冲突消解