乐途乐途
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
  • 学习路径
  • 第1章 多模块项目深入

    • Reactor构建顺序
    • 继承与聚合组合实践
    • 模块间依赖
  • 第2章 插件体系深入

    • 插件目标goal
    • execution与自定义绑定
    • pluginManagement
  • 第3章 Profile高级应用

    • Profile激活机制
    • Profile与Spring Profile区别
  • 第4章 部署与分发

    • distributionManagement
    • mvn deploy
    • settings.xml认证配置
  • 第5章 CI/CD集成

    • Maven与持续集成
  • 第6章 自定义插件开发

    • 自定义插件开发
  • 第7章 高级依赖管理

    • 快照版本机制
    • 依赖分析工具
  • 第8章 仓库管理深入

    • 仓库组与路由

mvn deploy

本章承接distributionManagement的配置讲解,专门解析mvn deploy命令的执行机制。入门教程已覆盖mvn install(本地安装),本章解决"远程部署"与"本地安装"的本质差异,以及SNAPSHOT版本在团队协作中的特殊行为。


核心机制

mvn deploy是Maven生命周期中deploy阶段的触发命令。它的核心职责是:将当前项目的构建产物(主jar、pom、源码包、文档包等)从本地推送到远程仓库,使团队其他成员或下游系统能够通过坐标引用这些构件。

deploy与install的本质区别

维度mvn installmvn deploy
目标仓库本地仓库(~/.m2/repository)远程仓库(由distributionManagement指定)
生命周期阶段installdeploy
前置阶段自动执行validate到package的所有阶段自动执行validate到install的所有阶段
可访问范围仅本机用户整个团队或公网用户
构件持久性本地可随意删除由私服管理,Release不可覆盖
认证要求无需认证需要settings.xml中server认证

关键洞察:deploy不是install的"升级版",而是install的"延伸版"。执行deploy时,Maven会先完成install的全部工作(编译、测试、打包、安装到本地),然后再额外执行上传远程的操作。install是deploy的必要前置,而非可选项。

deploy生命周期流程

deploy阶段绑定的是maven-deploy-plugin:deploy目标。完整的执行链如下:

  1. validate → 验证pom.xml结构
  2. compile → 编译主代码
  3. test-compile → 编译测试代码
  4. test → 运行单元测试
  5. package → 打包成jar/war
  6. verify → 运行集成测试和检查
  7. install → 安装到本地仓库
  8. deploy → 上传到远程仓库(distributionManagement指定)

SNAPSHOT部署的特殊行为

SNAPSHOT版本(如1.2.0-SNAPSHOT)在deploy时有三个特殊规则:

  1. 时间戳命名:上传后,私服会自动在文件名中加入时间戳和构建号,如order-service-1.2.0-20240115.083022-1.jar。本地Maven解析SNAPSHOT依赖时,会下载最新的时间戳版本。
  2. 允许覆盖:同一SNAPSHOT可以反复deploy,每次都会生成新的时间戳文件,旧文件保留(可配置清理策略)。
  3. metadata.xml更新:私服会自动更新maven-metadata.xml,记录最新版本的时间戳,供客户端判断是否需要重新下载。

生活类比:图书馆系统

想象Maven仓库是一所大学图书馆:

  • mvn install:你把写好的论文复印一份,放进自己宿舍的书架(本地仓库)。只有你自己能看,室友来借也没有。
  • mvn deploy:你把论文正式提交到图书馆(远程仓库),编入索引系统。全校师生都能通过索书号(GAV坐标)借阅,而且图书馆会永久保存。
  • SNAPSHOT:你提交的是"草稿版"(Snapshot)。图书馆允许你每周更新草稿,每次更新都会在封面上贴新的日期标签(时间戳)。借阅者每次来借,都能拿到最新的一版草稿。
  • RELEASE:你提交的是"定稿版"(Release)。图书馆规定定稿一旦上架,永远不可修改。如果有人引用你的结论,十年后他再来借,内容完全一致——这就是可复现性。

图示

deploy生命周期流程图

上图展示了mvn deploy的完整生命周期。install阶段(黄色)是deploy的必经之路——构件必须先进入本地仓库,才能被deploy插件读取并上传。deploy阶段本身(绿色)根据version类型分叉:SNAPSHOT走时间戳命名路径,Release保持原始版本号。

deploy前后仓库状态对比

上图对比了deploy执行前后的仓库状态。install只影响本地仓库,deploy在install的基础上把同样的内容复制到远程仓库。注意远程仓库会额外生成maven-metadata.xml,这是私服用于版本索引和SNAPSHOT解析的关键文件。


完整示例

场景

飞翔科技的order-service进入1.2.0版本迭代。CTO大翔要求:

  1. 小崔每天下班前deploy当天的SNAPSHOT,黄俪第二天联调时自动拿到最新版
  2. 白歌在版本稳定后deploy RELEASE,李眉部署到生产环境时引用固定版本
  3. 所有deploy操作必须经过单元测试(test阶段不能跳过)

小崔的SNAPSHOT日常部署

# 小崔完成功能开发,当前pom.xml版本为 1.2.0-SNAPSHOT
cd order-service

# 执行完整deploy(包含测试)
mvn clean deploy

# 控制台输出关键片段:
# [INFO] --- maven-deploy-plugin:2.8.2:deploy (default-deploy) @ order-service ---
# [INFO] Uploading to feixiang-snapshots: https://nexus.feixiang.com/...
# [INFO] Uploaded: order-service-1.2.0-20240115.083022-1.jar (45 kB)
# [INFO] Uploaded: order-service-1.2.0-20240115.083022-1.pom (3 kB)
# [INFO] Uploading: maven-metadata.xml

黄俪(前端)的联调pom.xml:

<dependency>
    <groupId>com.feixiang</groupId>
    <artifactId>order-service</artifactId>
    <version>1.2.0-SNAPSHOT</version>
</dependency>

黄俪执行mvn compile时,Maven会检查私服上的maven-metadata.xml,自动下载1.2.0-SNAPSHOT的最新时间戳版本。如果小崔昨晚又deploy了一次,黄俪今天会拿到-2版本。

白歌的RELEASE正式发布

# 1. 移除SNAPSHOT后缀
mvn versions:set -DnewVersion=1.2.0

# 2. 确认所有测试通过
mvn clean test

# 3. 部署到发布仓库
mvn clean deploy

# 控制台输出关键片段:
# [INFO] --- maven-deploy-plugin:2.8.2:deploy (default-deploy) @ order-service ---
# [INFO] Uploading to feixiang-releases: https://nexus.feixiang.com/...
# [INFO] Uploaded: order-service-1.2.0.jar (45 kB)
# [INFO] Uploaded: order-service-1.2.0.pom (3 kB)

李眉(运维)的生产引用:

<dependency>
    <groupId>com.feixiang</groupId>
    <artifactId>order-service</artifactId>
    <version>1.2.0</version>  <!-- 固定版本,永不变动 -->
</dependency>

易错点与常见问题

误区一:deploy可以跳过install

错误认知:"我只想把jar传到远程,本地仓库不需要留一份,所以能不能只执行deploy不执行install?"

纠正:不能。deploy阶段在生命周期中位于install之后,执行deploy必然先执行install。即使你显式指定mvn deploy -DskipTests,install阶段仍然会发生。这是设计上的强制顺序——deploy插件从本地仓库读取构件上传,而非从target目录直接读取。

反例:

# 试图跳过install,直接deploy
mvn deploy -Dskip.install=true
# 结果:Maven不认识skip.install参数,install照常执行

如果你确实不想污染本地仓库(比如在CI环境中),可以在deploy后清理,或者使用-Dmaven.repo.local=/tmp/empty-repo指定一个临时本地仓库。

误区二:SNAPSHOT deploy后本地缓存不刷新

错误认知:"小崔deploy了新的SNAPSHOT,但我(黄俪)执行mvn compile还是拿到昨天的版本。"

纠正:Maven默认每天只检查一次SNAPSHOT更新。如果你今天已经编译过,Maven会把SNAPSHOT缓存到本地,直到第二天才重新检查远程。强制刷新需要:

# 方式一:强制更新所有SNAPSHOT
mvn compile -U
# -U = --update-snapshots

# 方式二:强制更新特定依赖
mvn dependency:purge-local-repository -DactTransitively=false \
    -DmanualInclude=com.feixiang:order-service

反例:黄俪的pom.xml里写了1.2.0-SNAPSHOT,但她连续三天没有加-U,一直用着三天前的jar包,联调时反复出现"小崔说已经修了但黄俪还是报错"的诡异现象。

误区三:RELEASE版本重复deploy

错误认知:"1.2.0有个小bug,我改完代码重新deploy一下,覆盖掉之前的。"

纠正:Release仓库默认禁止覆盖。Nexus/Artifactory等私服对Release仓库有"deploy once"策略,防止已发布的固定版本被篡改。如果你尝试重新deploy 1.2.0:

Return code is: 400, ReasonPhrase: Bad Request
Repository does not allow updating assets: maven-releases

正确做法:

  1. 如果是紧急修复,升级版本号重新deploy(如1.2.1)
  2. 如果确实需要覆盖(不推荐),在Nexus管理界面临时开启"Allow redeploy",但会破坏下游的可复现性

小结

mvn deploy是Maven生命周期中最后一个阶段,它在mvn install的基础上,将构件推送到远程仓库供团队共享。核心要点:

  1. deploy包含install,不是替代关系
  2. SNAPSHOT部署生成时间戳,支持反复覆盖,适合持续集成
  3. RELEASE部署不可覆盖,保证构建可复现性
  4. SNAPSHOT消费端需要-U参数强制刷新,否则可能拿到过期缓存

理解deploy与install的分工,以及SNAPSHOT的特殊治理规则,是团队协作中构件分发的基本功。

本章与全局的关系:本章讲解了deploy命令的执行机制。下一章将深入settings.xml的servers认证配置,解决"远程仓库凭什么让你上传"的权限问题。

上一页
distributionManagement
下一页
settings.xml认证配置