一、Maven 仓库概述
Maven仓库是存储项目依赖(jar包、插件等)的地方。Maven通过坐标(groupId, artifactId, version)来定位和获取这些依赖。仓库分为本地仓库和远程仓库。
二、Maven 仓库架构体系
2.1 三级仓库架构
bash
┌──────────────────────────────────────────────────────────┐
│ 远程仓库 (Remote Repositories) │
├──────────────────────────────────────────────────────────┤
│ 中央仓库 私服仓库 第三方仓库 │
│ (Central) (Private) (3rd Party) │
└──────────────┬──────────────┬──────────────┬─────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────┐
│ 本地仓库 (Local Repository) │
│ ~/.m2/repository 或自定义路径 │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 项目依赖 (Project Dependencies) │
│ pom.xml 中声明的依赖坐标 │
└─────────────────────────────────────────────────────────┘
2.2 Maven 仓库类型
Maven 的仓库可分为 本地仓库 和 远程仓库 ,远程仓库又可以细分为 中央仓库 、私服仓库 和 第三方仓库。
bash
Maven 仓库体系
├── 本地仓库 (Local Repository)
├── 远程仓库 (Remote Repository)
│ ├── 中央仓库 (Central Repository)
│ ├── 第三方公共仓库 (Third-party Repositories)
│ └── 私有仓库 (Private Repository/Nexus/Artifactory)
- 本地仓库(Local Repository)
- 定义:开发者本地计算机上的 Maven 依赖存储目录
- 作用:缓存远程依赖、存储本地构建产物
- 位置:默认在用户主目录的 .m2/repository 下
- 特点:私有的、本地的、持久化的依赖仓库
- 中央仓库 (Central Repository)
- 官方名称: Maven Central Repository
- 维护者: Sonatype(受 Maven 社区管理)
- URL: https://repo.maven.apache.org/maven2/
- 镜像URL: https://repo1.maven.org/maven2/
- 状态: 全球 Java 生态系统的标准仓库
- 第三方公共仓库 (Third-party Repositories)
- 国内访问快
- 镜像中央仓库
- 私有仓库 (Private Repository/Nexus/Artifactory)
- 加速构建(本地网络访问)
- 存储内部私有构件
- 控制外部依赖访问
- 审计和安全性控制
三、本地仓库管理
3.1 本地仓库配置
xml
<!-- settings.xml 中配置 -->
<settings>
<!-- 修改本地仓库位置 -->
<localRepository>D:\maven-repository</localRepository>
<!-- 或 -->
<localRepository>/opt/maven/repository</localRepository>
</settings>
3.2 本地仓库管理命令
bash
# 清理本地仓库
mvn dependency:purge-local-repository
# 清理指定依赖
mvn dependency:purge-local-repository -DmanualInclude="groupId:artifactId"
# 清理过期快照
mvn dependency:purge-local-repository -DsnapshotsOnly=true
# 重新下载依赖
mvn dependency:purge-local-repository -DreResolve=true
# 查看本地仓库大小
du -sh ~/.m2/repository
# Windows: dir /s | find "File(s)"
# 统计依赖数量
find ~/.m2/repository -name "*.jar" | wc -l
3.3 本地仓库缓存策略
bash
# 缓存失效机制
# _remote.repositories 文件记录仓库来源和最后更新时间
cat ~/.m2/repository/com/google/guava/guava/31.1-jre/_remote.repositories
# 强制更新缓存
mvn clean install -U # 强制更新快照依赖
mvn clean install -U -Dmaven.wagon.http.retryHandler.count=3 # 带重试的更新
四、远程仓库配置
4.1 仓库配置位置
xml
<!-- 1. settings.xml (全局/用户级) -->
<settings>
<profiles>
<profile>
<repositories>
<repository>
<id>company-repo</id>
<url>http://nexus.company.com/repository/maven-public/</url>
</repository>
</repositories>
</profile>
</profiles>
</settings>
<!-- 2. pom.xml (项目级) -->
<project>
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
</project>
4.2 仓库详细配置
xml
<repository>
<!-- 唯一标识符 -->
<id>company-snapshots</id>
<!-- 仓库名称 -->
<name>Company Snapshot Repository</name>
<!-- 仓库URL -->
<url>http://nexus.company.com/repository/snapshots/</url>
<!-- 布局类型 (默认: default) -->
<layout>default</layout>
<!-- 发布版本配置 -->
<releases>
<enabled>true</enabled>
<!-- 更新策略 -->
<updatePolicy>daily</updatePolicy> <!-- never, always, daily, interval:X -->
<!-- 校验和策略 -->
<checksumPolicy>warn</checksumPolicy> <!-- fail, warn, ignore -->
<!-- 仅当缺失时下载 -->
<downloadWhenMissingOnly>false</downloadWhenMissingOnly>
</releases>
<!-- 快照版本配置 -->
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
</repository>
4.3 更新策略详解
| 策略值 | 含义 | 适用场景 |
|---|---|---|
| always | 每次检查更新 | 快照版本 (SNAPSHOT) |
| daily | 每天检查一次(默认) | 稳定版本 |
| interval:X | 每 X 分钟检查 | 测试环境 |
| never | 从不检查 | 离线环境 |
xml
<!-- updatePolicy 选项 -->
<updatePolicy>always</updatePolicy> <!-- 每次构建都检查更新 -->
<updatePolicy>daily</updatePolicy> <!-- 每天第一次构建检查更新(默认) -->
<updatePolicy>interval:60</updatePolicy> <!-- 每60分钟检查更新 -->
<updatePolicy>never</updatePolicy> <!-- 从不检查更新 -->
<!-- checksumPolicy 选项 -->
<checksumPolicy>ignore</checksumPolicy> <!-- 忽略校验和错误 -->
<checksumPolicy>fail</checksumPolicy> <!-- 校验和失败时构建失败 -->
<checksumPolicy>warn</checksumPolicy> <!-- 校验和失败时警告(默认) -->
4.4 校验和策略
fail:校验失败时构建失败warn:校验失败时警告(默认)ignore:忽略校验失败
xml
<checksumPolicy>fail</checksumPolicy> <!-- 校验失败则构建失败 -->
<checksumPolicy>warn</checksumPolicy> <!-- 校验失败只警告 -->
<checksumPolicy>ignore</checksumPolicy> <!-- 忽略校验失败 -->
五、中央仓库
Maven 中央仓库(Central Repository)是 Maven 生态系统中最重要、最核心的公共仓库。
5.1 中央仓库特点
- 权威性
- 所有构件都经过严格审核
- 必须符合 Maven 发布规范
- 提供 PGP 签名验证
- 包含完整的元数据
- 完整性
- 包含 Java 生态系统绝大多数开源库
- 截至2024年,包含超过 500万 个构件
- 日下载量超过 10亿次
- 支持 Java 5 到最新版本
- 稳定性
- 遵循语义化版本控制
- 构件一旦发布永不修改
- 提供版本快照(但较少使用)
- 保持向后兼容性
5.2 访问方式
Maven 默认配置中央仓库,无需额外配置:
xml
<!-- pom.xml 中配置(通常默认包含) -->
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled> <!-- 中央仓库不存储快照 -->
</snapshots>
<releases>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy> <!-- 更新策略 -->
<checksumPolicy>warn</checksumPolicy> <!-- 校验和策略 -->
</releases>
</repository>
</repositories>
5.3 超级POM中的定义
所有 Maven 项目都继承此配置:
xml
<!-- Maven 3.5.0+ 超级POM片段 -->
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
5.4 全球镜像网络
由于访问量大,中央仓库有全球镜像:
5.5 发布机制
5.5.1 发布要求
要发布到中央仓库,必须满足:
xml
<!-- 1. 正确的坐标 -->
<groupId>com.example</groupId> <!-- 域名倒置 -->
<artifactId>my-library</artifactId>
<version>1.0.0</version>
<!-- 2. 必要的元数据 -->
<name>My Library</name>
<description>A useful library</description>
<url>https://github.com/example/my-library</url>
<licenses>
<license>
<name>Apache License 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<!-- 3. SCM信息 -->
<scm>
<connection>scm:git:git://github.com/example/my-library.git</connection>
<developerConnection>scm:git:ssh://github.com:example/my-library.git</developerConnection>
<url>https://github.com/example/my-library</url>
</scm>
5.5.2 发布流程

5.5.3 发布工具
bash
# 使用 Maven 部署插件
mvn clean deploy
# 发布到 OSSRH(暂存仓库)
mvn clean deploy -P release
# 从 OSSRH 发布到中央仓库
mvn nexus-staging:release
六、第三方仓库
6.1 主流第三方公共仓库
xml
<repositories>
<repository>
<id>aliyun-public</id>
<name>Aliyun Public Repository</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<!-- 阿里云中央仓库镜像 -->
<repository>
<id>aliyun-central</id>
<name>Aliyun Central Mirror</name>
<url>https://maven.aliyun.com/nexus/content/repositories/central</url>
</repository>
<!-- 华为云 Maven 仓库 -->
<repository>
<id>huaweicloud</id>
<name>HuaweiCloud Repository</name>
<url>https://repo.huaweicloud.com/repository/maven/</url>
</repository>
<!-- 腾讯云 Maven 仓库 -->
<repository>
<id>tencent</id>
<name>Tencent Cloud Repository</name>
<url>https://mirrors.cloud.tencent.com/nexus/repository/maven-public/</url>
</repository>
</repositories>
6.3 特定框架/语言仓库
6.3.1 Spring 仓库
Spring 框架相关依赖的仓库。
xml
<repositories>
<!-- Spring Milestone 仓库(预发布版本) -->
<repository>
<id>spring-milestone</id>
<name>Spring Milestone Repository</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<!-- Spring 快照仓库(开发版本) -->
<repository>
<id>spring-snapshot</id>
<name>Spring Snapshot Repository</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<!-- Spring Releases 仓库(正式版本) -->
<repository>
<id>spring-releases</id>
<name>Spring Releases Repository</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
6.3.2 Apache 仓库
Apache 项目相关依赖。
xml
<repositories>
<!-- Apache 快照仓库 -->
<repository>
<id>apache-snapshots</id>
<name>Apache Snapshot Repository</name>
<url>https://repository.apache.org/snapshots</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<!-- Apache 发布仓库 -->
<repository>
<id>apache-releases</id>
<name>Apache Release Repository</name>
<url>https://repository.apache.org/releases</url>
</repository>
</repositories>
6.3.3 JBoss 仓库
JBoss/Red Hat 相关依赖。
xml
<repositories>
<!-- JBoss Releases -->
<repository>
<id>jboss-releases</id>
<name>JBoss Release Repository</name>
<url>https://repository.jboss.org/nexus/content/repositories/releases</url>
</repository>
<!-- JBoss 第三方依赖 -->
<repository>
<id>jboss-thirdparty</id>
<name>JBoss Thirdparty Repository</name>
<url>https://repository.jboss.org/nexus/content/repositories/thirdparty-releases</url>
</repository>
</repositories>
6.3.4 Clojars 仓库
Clojure 生态系统的仓库。
xml
<repositories>
<repository>
<id>clojars</id>
<name>Clojars Repository</name>
<url>https://repo.clojars.org</url>
</repository>
</repositories>
6.3.5 Google Maven 仓库
Android 和 Google 相关依赖。
xml
<repositories>
<repository>
<id>google-maven</id>
<name>Google Maven Repository</name>
<url>https://maven.google.com</url>
</repository>
</repositories>
七、私有仓库
Maven 私有仓库是企业级开发中至关重要的基础设施,用于管理内部构件、加速依赖下载、控制外部访问等。
7.1 主流私有仓库产品对比
| 特性 | Nexus Repository | JFrog Artifactory | Apache Archiva |
|---|---|---|---|
| 厂商 | Sonatype | JFrog | Apache |
| 许可证 | OSS/Pro | OSS/Pro | Apache 2.0 |
| 部署方式 | WAR/Docker | WAR/Docker/云 | WAR |
| 性能 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| 易用性 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| 多格式支持 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ |
| 企业特性 | Pro版 | Pro版 | 基础 |
| 社区活跃度 | 高 | 高 | 中 |
选型建议:
- 中小企业/初创:Nexus OSS
- 大型企业/云原生:Artifactory Pro
- 简单需求/预算有限:Archiva
7.2 Nexus Repository 3.x 详细配置
7.2.1 快速部署
bash
# Docker 部署 Nexus 3
docker run -d \
--name nexus \
-p 8081:8081 \
-p 8082:8082 \
-v nexus-data:/nexus-data \
sonatype/nexus3:latest
# 初始密码
admin / admin123
7.2.2 仓库类型配置
bash
# Nexus 仓库类型
仓库类型:
proxy: # 代理仓库
- maven-central
- google-maven
- jcenter
hosted: # 托管仓库
- maven-releases # 发布版本
- maven-snapshots # 快照版本
- maven-internal # 内部库
group: # 仓库组
- maven-public # 对外统一入口
7.2.3 仓库创建与配置
bash
// Nexus REST API 创建仓库
POST /service/rest/v1/repositories/maven/hosted
Content-Type: application/json
{
"name": "company-releases",
"online": true,
"storage": {
"blobStoreName": "default",
"strictContentTypeValidation": true,
"writePolicy": "ALLOW_ONCE"
},
"maven": {
"versionPolicy": "RELEASE",
"layoutPolicy": "STRICT"
}
}
7.2.4 仓库策略设计
yaml
# 企业多环境配置
environments:
dev:
repositories:
- name: dev-snapshots
type: hosted
policy: snapshot
cleanup_policy: 7天保留
- name: dev-releases
type: hosted
policy: release
cleanup_policy: 30天保留
- name: dev-proxy
type: proxy
url: https://repo.maven.apache.org/maven2
staging:
repositories:
- name: staging-releases
type: hosted
policy: release
promotion: 手动
production:
repositories:
- name: prod-releases
type: hosted
policy: release
immutable: true
audit: 开启
7.2.5 清理策略配置
bash
// Nexus 清理策略
{
"name": "cleanup-snapshots",
"format": "maven2",
"criteria": {
"lastDownloaded": 30, // 30天未下载
"lastBlobUpdated": 90, // 90天未更新
"regex": ".*-SNAPSHOT$" // 匹配快照
},
"action": {
"type": "delete"
}
}
7.3 客户端配置
7.3.1 Maven settings.xml 配置
xml
<!-- 完整的企业 settings.xml 示例 -->
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0">
<!-- 仓库镜像(所有请求转到私有仓库) -->
<mirrors>
<mirror>
<id>company-mirror</id>
<name>Company Repository Group</name>
<url>http://nexus.company.com/repository/maven-public/</url>
<mirrorOf>external:*</mirrorOf>
</mirror>
</mirrors>
<!-- 服务器认证 -->
<servers>
<!-- 部署认证 -->
<server>
<id>company-releases</id>
<username>${env.DEPLOY_USER}</username>
<password>${env.DEPLOY_PASSWORD}</password>
</server>
<server>
<id>company-snapshots</id>
<username>${env.DEPLOY_USER}</username>
<password>${env.DEPLOY_PASSWORD}</password>
</server>
<!-- 只读认证(可选) -->
<server>
<id>company-public</id>
<username>readonly</username>
<password>readonly123</password>
</server>
</servers>
<!-- 配置Profile -->
<profiles>
<profile>
<id>company</id>
<!-- 仓库配置 -->
<repositories>
<repository>
<id>company-public</id>
<name>Company Repository</name>
<url>http://nexus.company.com/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
<!-- 插件仓库 -->
<pluginRepositories>
<pluginRepository>
<id>company-public</id>
<url>http://nexus.company.com/repository/maven-public/</url>
</pluginRepository>
</pluginRepositories>
<!-- 属性配置 -->
<properties>
<altReleaseDeploymentRepository>
company-releases::default::http://nexus.company.com/repository/maven-releases/
</altReleaseDeploymentRepository>
<altSnapshotDeploymentRepository>
company-snapshots::default::http://nexus.company.com/repository/maven-snapshots/
</altSnapshotDeploymentRepository>
</properties>
</profile>
</profiles>
<!-- 激活Profile -->
<activeProfiles>
<activeProfile>company</activeProfile>
</activeProfiles>
</settings>
7.3.2 项目 pom.xml 配置
xml
<project>
<!-- 发布仓库配置 -->
<distributionManagement>
<repository>
<id>company-releases</id>
<name>Company Release Repository</name>
<url>http://nexus.company.com/repository/maven-releases/</url>
<uniqueVersion>false</uniqueVersion>
<!-- 发布策略 -->
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</releases>
</repository>
<snapshotRepository>
<id>company-snapshots</id>
<name>Company Snapshot Repository</name>
<url>http://nexus.company.com/repository/maven-snapshots/</url>
<uniqueVersion>true</uniqueVersion>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</snapshotRepository>
<!-- 站点部署(可选) -->
<site>
<id>company-site</id>
<url>dav:http://nexus.company.com/sites/${project.groupId}/${project.artifactId}</url>
</site>
</distributionManagement>
<!-- 配置仓库(如果不使用镜像) -->
<repositories>
<repository>
<id>company-public</id>
<url>http://nexus.company.com/repository/maven-public</url>
</repository>
</repositories>
</project>
八、仓库镜像
Maven 仓库镜像是 Maven 体系中用于优化依赖下载速度、提高可用性和实现访问控制的重要机制。
8.1 镜像基础概念
- 定义:镜像是一个仓库的完整或部分副本,对外提供相同的服务
- 目的:替代或补充原始仓库,提供更好的访问体验
- 位置:通常位于离用户更近的网络位置
xml
<mirror>
<id>aliyun-mirror</id>
<name>Aliyun Mirror</name>
<url>https://maven.aliyun.com/repository/public</url>
<mirrorOf>central</mirrorOf> <!-- 替换中央仓库 -->
</mirror>
8.2 镜像工作原理
bash
原始仓库请求: https://repo.maven.apache.org/maven2/...
↓
镜像匹配: mirrorOf="central"
↓
重定向到: https://maven.aliyun.com/repository/public/...
8.3 镜像类型分类
按功能分类:
| 类型 | 特点 | 适用场景 | 示例 |
|---|---|---|---|
| 完全镜像 | 完整复制源仓库 | 提升访问速度 | 阿里云镜像 |
| 代理镜像 | 按需缓存,透明代理 | 企业内部访问控制 | Nexus代理 |
| 聚合镜像 | 多个仓库聚合 | 统一访问入口 | 仓库组 |
| 过滤镜像 | 选择性镜像内容 | 安全策略 | 只镜像特定组织 |
按部署位置分类:
bash
镜像层级:
- 全球公共镜像: 阿里云、华为云等
- 国家/地区镜像: 教育网镜像、科技网镜像
- 企业私有镜像: 公司内部部署
- 团队本地镜像: 开发团队共享
- 个人缓存镜像: 开发机本地代理
8.4 国内镜像仓库配置
xml
<!-- settings.xml 镜像配置 -->
<mirrors>
<!-- 阿里云镜像(推荐) -->
<mirror>
<id>aliyun-maven</id>
<mirrorOf>central</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
<!-- 华为云镜像 -->
<mirror>
<id>huawei-central</id>
<mirrorOf>central</mirrorOf>
<name>华为云仓库</name>
<url>https://repo.huaweicloud.com/repository/maven/</url>
</mirror>
<!-- 腾讯云镜像 -->
<mirror>
<id>tencent</id>
<mirrorOf>central</mirrorOf>
<name>腾讯云仓库</name>
<url>https://mirrors.cloud.tencent.com/nexus/repository/maven-public/</url>
</mirror>
<!-- 网易镜像 -->
<mirror>
<id>netease</id>
<mirrorOf>central</mirrorOf>
<name>网易镜像</name>
<url>https://mirrors.163.com/maven/repository/maven-public/</url>
</mirror>
<!-- 自定义镜像规则 -->
<mirror>
<id>internal-repository</id>
<mirrorOf>external:*</mirrorOf> <!-- 匹配所有external开头的仓库 -->
<name>内部仓库代理</name>
<url>http://nexus.internal.com/repository/maven-public/</url>
</mirror>
<!-- 排除特定仓库 -->
<mirror>
<id>nexus</id>
<mirrorOf>*,!my-internal-repo</mirrorOf> <!-- 排除my-internal-repo -->
<name>内部Nexus</name>
<url>http://nexus.company.com/repository/maven-public/</url>
</mirror>
</mirrors>
8.5 镜像匹配规则
mirrorOf 是 Maven 镜像配置中的核心元素,用于指定该镜像替换哪些仓库。它定义了镜像的覆盖范围和匹配规则。
| 模式 | 示例 | 说明 |
|---|---|---|
| 精确匹配 | central | 匹配特定仓库ID |
| 通配符匹配 | * | 匹配所有仓库 |
| 排除匹配 | *,!repo1 | 匹配除repo1外的所有仓库 |
| 列表匹配 | repo1,repo2 | 匹配多个仓库 |
| 模式匹配 | external:* | 匹配模式化仓库 |
xml
<!-- 多种匹配模式 -->
<mirrorOf>*</mirrorOf> <!-- 匹配所有仓库 -->
<mirrorOf>external:*</mirrorOf> <!-- 匹配所有external仓库 -->
<mirrorOf>repo1,repo2</mirrorOf> <!-- 匹配repo1和repo2 -->
<mirrorOf>*,!repo1</mirrorOf> <!-- 匹配除repo1外的所有仓库 -->
<mirrorOf>*</mirrorOf> <!-- 最简单,匹配所有 -->
<!-- 常用仓库ID -->
<mirrorOf>central</mirrorOf> <!-- 中央仓库 -->
<mirrorOf>apache.snapshots</mirrorOf> <!-- Apache快照仓库 -->
<mirrorOf>jboss-public-repository-group</mirrorOf> <!-- JBoss仓库 -->
8.6 mirrorOf 优先级与冲突解决
8.6.1 镜像匹配优先级
-
Maven 按照 中定义的顺序进行匹配,使用第一个匹配的镜像。
xml<!-- settings.xml --> <mirrors> <!-- 这个会生效(因为是第一个匹配的) --> <mirror> <id>mirror1</id> <url>http://mirror1.company.com</url> <mirrorOf>central</mirrorOf> <!-- 这个生效 --> </mirror> <!-- 这个永远不会被使用(如果mirror1匹配成功) --> <mirror> <id>mirror2</id> <url>http://mirror2.company.com</url> <mirrorOf>central</mirrorOf> <!-- 这个被忽略 --> </mirror> <!-- 这个可能生效(如果前面都不匹配) --> <mirror> <id>mirror3</id> <url>http://mirror3.company.com</url> <mirrorOf>*</mirrorOf> <!-- 通用备用镜像 --> </mirror> </mirrors> -
精确匹配优先于模糊匹配
xml<mirrors> <!-- 模糊匹配:匹配所有仓库 --> <mirror> <id>general-mirror</id> <url>http://general.company.com</url> <mirrorOf>*</mirrorOf> <!-- 低优先级 --> </mirror> <!-- 精确匹配:只匹配中央仓库 --> <mirror> <id>central-mirror</id> <url>http://central.company.com</url> <mirrorOf>central</mirrorOf> <!-- 高优先级 --> </mirror> </mirrors> <!-- 结果:当请求中央仓库时,使用 central-mirror --> -
多配置文件中的优先级
Maven 按以下顺序加载配置文件:
bash1. 项目pom.xml的 <repositories> 2. 用户settings.xml (~/.m2/settings.xml) 3. 全局settings.xml ($M2_HOME/conf/settings.xml)镜像配置优先级:settings.xml 中的镜像会覆盖 pom.xml 中的仓库配置。
8.6.2 镜像冲突解决
-
多个镜像匹配同一仓库
xml<mirrors> <!-- 配置A:阿里云镜像 --> <mirror> <id>aliyun</id> <url>https://maven.aliyun.com/repository/central</url> <mirrorOf>central</mirrorOf> </mirror> <!-- 配置B:华为云镜像(冲突!) --> <mirror> <id>huawei</id> <url>https://repo.huaweicloud.com/repository/maven</url> <mirrorOf>central</mirrorOf> </mirror> <!-- 配置C:腾讯云镜像(冲突!) --> <mirror> <id>tencent</id> <url>https://mirrors.cloud.tencent.com/nexus/repository/maven-public</url> <mirrorOf>central</mirrorOf> </mirror> </mirrors> <!-- 结果:只使用 aliyun(第一个匹配的) --> -
重叠匹配范围
bash<mirrors> <!-- 匹配所有仓库 --> <mirror> <id>mirror-all</id> <url>http://mirror1.company.com</url> <mirrorOf>*</mirrorOf> </mirror> <!-- 匹配特定仓库 --> <mirror> <id>mirror-specific</id> <url>http://mirror2.company.com</url> <mirrorOf>my-repo</mirrorOf> </mirror> </mirrors> <!-- 解析结果: 1. 请求 my-repo:使用 mirror-specific(更精确) 2. 请求其他仓库:使用 mirror-all --> -
排除模式冲突
bash<mirrors> <!-- 排除特定仓库 --> <mirror> <id>mirror-except-internal</id> <url>http://mirror1.company.com</url> <mirrorOf>*,!internal-repo</mirrorOf> </mirror> <!-- 包含所有仓库(冲突!) --> <mirror> <id>mirror-all</id> <url>http://mirror2.company.com</url> <mirrorOf>*</mirrorOf> </mirror> </mirrors> <!-- 结果:internal-repo 会使用 mirror-all(因为第一个不匹配) -->
8.7 mirrorOf 与仓库配置的关系
8.7.1 镜像 vs 仓库
xml
<!-- 仓库配置 -->
<repositories>
<repository>
<id>my-repo</id>
<url>http://my.company.com/repo</url>
</repository>
</repositories>
<!-- 镜像配置 -->
<mirrors>
<mirror>
<id>mirror-for-my-repo</id>
<url>http://mirror.company.com/repo</url>
<mirrorOf>my-repo</mirrorOf> <!-- 镜像替换这个仓库 -->
</mirror>
</mirrors>
关键区别:
- 仓库:定义从哪里获取依赖
- 镜像:定义如何重定向仓库请求
8.7.2 镜像不影响仓库声明的顺序
xml
<repositories>
<!-- 仓库声明的顺序很重要 -->
<repository>
<id>repo1</id> <!-- 先查找 -->
<url>http://repo1</url>
</repository>
<repository>
<id>repo2</id> <!-- 后查找 -->
<url>http://repo2</url>
</repository>
</repositories>
<mirrors>
<!-- 镜像不影响查找顺序,只影响目标URL -->
<mirror>
<id>mirror-all</id>
<url>http://mirror.all</url>
<mirrorOf>repo1,repo2</mirrorOf> <!-- 两个仓库都被镜像 -->
</mirror>
</mirrors>
九、仓库认证与安全
9.1 认证配置
xml
<settings>
<servers>
<!-- 用户名密码认证 -->
<server>
<id>my-server</id>
<username>myuser</username>
<password>mypass</password>
</server>
<!-- 加密密码 -->
<server>
<id>secure-server</id>
<username>secure-user</username>
<password>{加密后的密码}</password>
</server>
<!-- 私钥认证 -->
<server>
<id>ssh-server</id>
<username>git</username>
<privateKey>${user.home}/.ssh/id_rsa</privateKey>
<passphrase>optional-passphrase</passphrase>
</server>
<!-- 文件权限认证 -->
<server>
<id>file-server</id>
<username></username>
<password></password>
<filePermissions>664</filePermissions>
<directoryPermissions>775</directoryPermissions>
</server>
<!-- 配置权限 -->
<server>
<id>config-server</id>
<configuration>
<httpHeaders>
<property>
<name>X-API-Key</name>
<value>my-api-key</value>
</property>
</httpHeaders>
</configuration>
</server>
</servers>
</settings>
9.2 密码加密
bash
# 生成主密码
mvn --encrypt-master-password
# 输入: masterpassword
# 输出: {加密后的主密码}
# 创建 settings-security.xml
cat > ~/.m2/settings-security.xml << EOF
<settingsSecurity>
<master>{加密后的主密码}</master>
</settingsSecurity>
EOF
# 加密服务器密码
mvn --encrypt-password
# 输入: serverpassword
# 输出: {加密后的服务器密码}
9.3 SSL/TLS 配置
bash
<settings>
<!-- 信任证书 -->
<servers>
<server>
<id>ssl-server</id>
<configuration>
<ssl>
<trustStore>${user.home}/.keystore</trustStore>
<trustStorePassword>keystorepass</trustStorePassword>
<clientCertificate>${user.home}/client.crt</clientCertificate>
</ssl>
</configuration>
</server>
</servers>
<!-- 代理配置 -->
<proxies>
<proxy>
<id>https-proxy</id>
<active>true</active>
<protocol>https</protocol>
<host>proxy.company.com</host>
<port>443</port>
<username>proxyuser</username>
<password>proxypass</password>
<nonProxyHosts>localhost|*.company.com</nonProxyHosts>
</proxy>
</proxies>
</settings>
十、多仓库配置策略
10.1 仓库优先级与顺序
10.1.1 核心查找流程
bash
1. 本地仓库 (~/.m2/repository)
↓
2. settings.xml 中的镜像仓库
↓
3. 项目pom.xml中的仓库
↓
4. 超级POM中的仓库
↓
5. settings.xml中的profile仓库
核心原则:
- 本地优先:始终先检查本地仓库
- 镜像覆盖:镜像配置会覆盖原仓库URL
- 就近原则:按配置顺序查找依赖
- 首次匹配:找到即停止搜索
10.1.2 镜像仓库的覆盖规则
xml
<!-- settings.xml中的镜像配置优先级 -->
<mirrors>
<!-- 优先级1: 精确匹配 -->
<mirror>
<id>exact-central</id>
<url>http://mirror1.company.com</url>
<mirrorOf>central</mirrorOf> <!-- 精确匹配中央仓库 -->
</mirror>
<!-- 优先级2: 模式匹配 -->
<mirror>
<id>pattern-match</id>
<url>http://mirror2.company.com</url>
<mirrorOf>*,!internal</mirrorOf> <!-- 模式匹配 -->
</mirror>
<!-- 优先级3: 通用匹配 -->
<mirror>
<id>catch-all</id>
<url>http://mirror3.company.com</url>
<mirrorOf>*</mirrorOf> <!-- 通用匹配(最低优先级) -->
</mirror>
</mirrors>
10.1.3 配置文件加载顺序
Maven配置文件加载流程:
bash
项目根目录
↓
pom.xml(项目配置)
↓
用户settings.xml(~/.m2/settings.xml)
↓
全局settings.xml($M2_HOME/conf/settings.xml)
↓
超级POM(Maven内置默认配置)
↓
最终有效配置(Effective Configuration)
配置合并优先级(从高到低,高优先级会覆盖掉低优先级的相同属性):
- 命令行参数:-Dproperty=value
- 项目pom.xml:项目特定配置
- 用户settings.xml:用户级配置
- 全局settings.xml:系统级配置
- 超级POM:Maven默认配置
配置继承示例:
xml
<!-- 超级POM中的默认配置 -->
<repositories>
<repository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2</url>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
<!-- 用户settings.xml覆盖 -->
<repositories>
<repository>
<id>central</id>
<url>https://mirror.company.com/maven2</url> <!-- 覆盖URL -->
<snapshots><enabled>true</enabled></snapshots> <!-- 修改策略 -->
</repository>
</repositories>
<!-- 项目pom.xml再次覆盖 -->
<repositories>
<repository>
<id>central</id>
<url>https://custom.company.com/maven2</url> <!-- 最终使用的URL -->
<snapshots><enabled>false</enabled></snapshots> <!-- 最终策略 -->
</repository>
</repositories>
10.1.4 仓库声明的顺序重要性
xml
<!-- pom.xml -->
<repositories>
<!-- 仓库1:最先被查找(最高优先级) -->
<repository>
<id>company-releases</id>
<url>http://nexus.company.com/releases</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<!-- 仓库2:其次被查找 -->
<repository>
<id>company-snapshots</id>
<url>http://nexus.company.com/snapshots</url>
<releases><enabled>false</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
<!-- 仓库3:最后被查找(最低优先级) -->
<repository>
<id>thirdparty</id>
<url>http://nexus.company.com/thirdparty</url>
</repository>
</repositories>
10.1.5 Profile仓库的优先级
xml
<profiles>
<!-- Profile中的仓库按profile激活顺序 -->
<profile>
<id>dev</id>
<repositories>
<repository>
<id>dev-repo</id> <!-- 当dev profile激活时最先搜索 -->
<url>http://dev.company.com</url>
</repository>
</repositories>
</profile>
<profile>
<id>prod</id>
<repositories>
<repository>
<id>prod-repo</id> <!-- 当prod profile激活时最先搜索 -->
<url>http://prod.company.com</url>
</repository>
</repositories>
</profile>
</profiles>
<!-- 激活多个profile时的合并顺序:
按 <activeProfiles> 中声明的顺序合并
-->
10.1.6 冲突解决策略
-
相同依赖不同版本的冲突
xml<!-- 场景:多个仓库有相同依赖的不同版本 --> <repositories> <!-- 仓库A有 mylib-1.0.0 --> <repository> <id>repo-a</id> <url>http://repo-a.com</url> </repository> <!-- 仓库B有 mylib-2.0.0 --> <repository> <id>repo-b</id> <url>http://repo-b.com</url> </repository> </repositories> <!-- 解决策略:使用第一个找到的版本 如果repo-a先声明,使用1.0.0 如果repo-b先声明,使用2.0.0 --> -
镜像与仓库的冲突
xml<!-- 镜像会完全覆盖原仓库URL --> <mirrors> <mirror> <id>my-mirror</id> <url>http://mirror.company.com</url> <mirrorOf>repo-a</mirrorOf> </mirror> </mirrors> <repositories> <!-- 这个URL会被镜像覆盖 --> <repository> <id>repo-a</id> <url>http://original-repo.com</url> <!-- 实际使用mirror.company.com --> </repository> </repositories> -
本地与远程的版本冲突
bash# 本地有1.0.0,远程有2.0.0 # 策略取决于更新策略: # 场景1:更新策略为always # 结果:下载2.0.0,替换本地1.0.0 # 场景2:更新策略为never # 结果:使用本地1.0.0,忽略远程2.0.0 # 场景3:更新策略为daily # 结果:如果本地文件超过24小时,下载2.0.0 # 强制更新命令: mvn clean install -U # -U 强制更新快照
10.2 仓库组管理
10.2.1 仓库组概念
bash
仓库组(Repository Group):
┌── maven-public (仓库组)
│ ├── company-releases (宿主仓库)
│ ├── company-snapshots (宿主仓库)
│ ├── central-proxy (代理仓库)
│ ├── spring-milestones-proxy (代理仓库)
│ └── thirdparty (宿主仓库)
│
└── 用户统一访问:http://nexus.company.com/repository/maven-public/
10.2.2 仓库组配置
xml
<!-- 使用仓库组 -->
<repository>
<id>company-group</id>
<name>Company Repository Group</name>
<url>http://nexus.company.com/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
10.2.3 仓库组排序策略
bash
# Nexus仓库组配置(YAML格式)
# 排序策略影响依赖查找顺序
repositories:
- name: maven-public
memberRepositories:
- company-releases # 第一优先级
- company-snapshots # 第二优先级
- central-proxy # 第三优先级
- spring-milestones # 第四优先级
# 可选:仓库路由
routingRules:
- pattern: 'com/company/.*'
repositories:
- company-releases
- company-snapshots
10.3 多环境仓库配置
10.3.1 环境隔离配置
xml
<!-- settings.xml 多环境配置 -->
<settings>
<!-- 开发环境 -->
<profile>
<id>dev</id>
<repositories>
<repository>
<id>dev-releases</id>
<url>http://nexus.dev.company.com/repository/maven-releases/</url>
</repository>
<repository>
<id>dev-snapshots</id>
<url>http://nexus.dev.company.com/repository/maven-snapshots/</url>
</repository>
</repositories>
</profile>
<!-- 测试环境 -->
<profile>
<id>test</id>
<repositories>
<repository>
<id>test-releases</id>
<url>http://nexus.test.company.com/repository/maven-releases/</url>
</repository>
</repositories>
</profile>
<!-- 生产环境 -->
<profile>
<id>prod</id>
<repositories>
<repository>
<id>prod-releases</id>
<url>http://nexus.prod.company.com/repository/maven-releases/</url>
</repository>
</repositories>
<properties>
<!-- 生产环境禁用快照 -->
<allowSnapshots>false</allowSnapshots>
</properties>
</profile>
</settings>
10.3.2 环境激活配置
xml
<settings>
<profiles>
<!-- 默认开发环境 -->
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!-- 操作系统激活 -->
<profile>
<id>windows</id>
<activation>
<os>
<family>windows</family>
</os>
</activation>
</profile>
<!-- 环境变量激活 -->
<profile>
<id>ci</id>
<activation>
<property>
<name>env.CI</name>
<value>true</value>
</property>
</activation>
</profile>
</profiles>
</settings>
10.3.3 环境切换命令
bash
# 激活特定环境
mvn clean install -P dev
mvn clean deploy -P test
mvn clean package -P prod
# 多环境组合
mvn clean install -P dev,integration
# 环境变量控制
export MAVEN_PROFILES=prod
mvn clean install
# 检查激活的profile
mvn help:active-profiles
十一、部署到仓库
11.1 部署配置
xml
<!-- pom.xml 中的部署配置 -->
<project>
<distributionManagement>
<!-- 发布版本仓库 -->
<repository>
<id>company-releases</id>
<name>Company Release Repository</name>
<url>http://nexus.company.com/repository/maven-releases/</url>
<!-- 唯一版本策略 -->
<uniqueVersion>true</uniqueVersion>
</repository>
<!-- 快照版本仓库 -->
<snapshotRepository>
<id>company-snapshots</id>
<name>Company Snapshot Repository</name>
<url>http://nexus.company.com/repository/maven-snapshots/</url>
<!-- 快照唯一版本(带时间戳) -->
<uniqueVersion>true</uniqueVersion>
</snapshotRepository>
<!-- 站点部署 -->
<site>
<id>company-site</id>
<name>Company Site Repository</name>
<url>scp://webhost.company.com/var/www/sites/${project.artifactId}/</url>
</site>
<!-- 下载仓库(可选) -->
<downloadUrl>http://nexus.company.com/repository/maven-releases/</downloadUrl>
<!-- 仓库状态 -->
<status>none</status> <!-- none, converted, partner -->
</distributionManagement>
</project>
11.2 部署命令
bash
# 部署到仓库
mvn clean deploy # 标准部署
mvn clean deploy -DskipTests # 跳过测试部署
mvn clean deploy -P production # 使用生产配置部署
# 部署特定文件
mvn deploy:deploy-file # 部署文件到仓库
mvn deploy:deploy-file \
-DgroupId=com.company \
-DartifactId=my-library \
-Dversion=1.0.0 \
-Dpackaging=jar \
-Dfile=target/my-library.jar \
-Durl=http://nexus.company.com/repository/maven-releases/ \
-DrepositoryId=company-releases
# 强制部署(覆盖)
mvn deploy -DupdateReleaseInfo=true # 强制更新发布信息
11.3 部署验证
bash
# 验证部署
curl -u user:pass http://nexus.company.com/service/rest/v1/search?repository=maven-releases&name=my-library
# 查看部署内容
mvn dependency:get \
-Dartifact=com.company:my-library:1.0.0 \
-Ddest=./downloaded.jar
# 验证签名(如果使用GPG签名)
mvn clean deploy -Dgpg.skip=false
十二、仓库性能优化
12.1 网络优化
xml
<!-- settings.xml 网络配置 -->
<settings>
<!-- 连接池配置 -->
<servers>
<server>
<id>company-repo</id>
<configuration>
<httpConfiguration>
<all>
<connectionTimeout>30000</connectionTimeout>
<readTimeout>60000</readTimeout>
<!-- 连接池 -->
<maxTotalConnections>50</maxTotalConnections>
<maxConnectionsPerHost>10</maxConnectionsPerHost>
</all>
</httpConfiguration>
<!-- 重试策略 -->
<retries>3</retries>
<timeout>120</timeout>
</configuration>
</server>
</servers>
<!-- 代理配置 -->
<proxies>
<proxy>
<id>company-proxy</id>
<active>true</active>
<protocol>http</protocol>
<host>proxy.company.com</host>
<port>8080</port>
<nonProxyHosts>*.company.com|localhost</nonProxyHosts>
</proxy>
</proxies>
</settings>
12.2 缓存优化
bash
# 预下载依赖
mvn dependency:go-offline # 下载所有依赖到本地
mvn dependency:resolve-plugins # 解析所有插件
# 增量构建
mvn clean install -o # 离线模式
mvn clean install -DskipTests # 跳过测试
mvn clean install -Dmaven.test.skip=true # 完全跳过测试
# 并行下载
mvn clean install -T 4 # 4线程并行
export MAVEN_OPTS="-Dmaven.artifact.threads=10" # 并行下载线程数
12.3 仓库镜像优化
xml
<!-- 就近选择镜像 -->
<mirrors>
<!-- 中国地区使用阿里云 -->
<mirror>
<id>aliyun</id>
<url>https://maven.aliyun.com/repository/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
<!-- 欧洲地区使用Euro Apache -->
<mirror>
<id>europe-central</id>
<url>https://repo.maven.apache.org/maven2</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
12.4 仓库连接优化
xml
<settings>
<!-- 连接超时设置 -->
<profiles>
<profile>
<id>default</id>
<properties>
<maven.wagon.http.retryHandler.count>3</maven.wagon.http.retryHandler.count>
<maven.wagon.httpconnectionManager.timeout>60000</maven.wagon.httpconnectionManager.timeout>
<maven.wagon.socket.timeout>60000</maven.wagon.socket.timeout>
</properties>
</profile>
</profiles>
</settings>