mvn install
本章承接
mvn package,进入 default 生命周期的安装阶段。理解mvn install的作用和本地仓库机制,是掌握 Maven 多模块协作和依赖共享的基础——没有 install,你的 JAR 只是孤岛。
核心机制
install 阶段将打包产物安装到本地仓库,使其可以作为依赖被本地其他项目使用。
这句话的关键在于"本地仓库"(local repository)。Maven 的仓库体系分为三级:本地仓库(~/.m2/repository)、远程私有仓库(如 Nexus、Artifactory)、中央仓库(Maven Central)。mvn install 只操作本地仓库,不涉及网络上传。
install 阶段在生命周期中的位置
default 生命周期的完整阶段链:
... → compile → test → package → verify → install → deploy
执行 mvn install 时,Maven 会自动依次执行从 validate 到 install 的所有前置阶段。也就是说,mvn install 隐式包含了 compile、test 和 package。
谁在做真正的安装工作?
install 阶段默认绑定了 maven-install-plugin 的 install 目标。该插件负责:
- 将
target/目录中的打包产物(JAR/WAR/POM)复制到本地仓库 - 按照 GAV 坐标(
groupId/artifactId/version/)创建目录结构 - 同时复制 POM 文件到本地仓库的对应位置
本地仓库的目录结构
本地仓库默认位于用户主目录下的 .m2/repository/。一个已安装的构件在本地仓库中的路径遵循:
~/.m2/repository/
└── com/
└── feixiang/
└── employee-system/
└── 1.0.0/
├── employee-system-1.0.0.jar ← 主产物
├── employee-system-1.0.0.pom ← POM 文件
└── _remote.repositories ← 远程仓库元数据
目录层级由 GAV 坐标决定:
groupId(com.feixiang)→ 目录层级com/feixiang/artifactId(employee-system)→ 目录名employee-system/version(1.0.0)→ 版本目录1.0.0/
install 与 package 的区别
| 对比项 | mvn package | mvn install |
|---|---|---|
| 产物位置 | target/ 目录 | ~/.m2/repository/ 本地仓库 |
| 可被其他项目引用 | ❌ 不能 | ✅ 可以 |
| 执行的前置阶段 | 到 package | 到 install |
| 网络操作 | 无 | 无 |
| 使用场景 | 本地验证产物 | 多模块/多项目依赖共享 |
生活类比:图书馆借阅系统
想象一所大学图书馆(Maven 仓库体系):
mvn package相当于你在宿舍(target/)写完了一篇论文,打印了一份放在桌上。只有你自己能看到,其他同学无法引用你的成果。mvn install相当于你把论文提交到图书馆(本地仓库),编目上架。其他同学(其他 Maven 项目)可以通过书名和编号(GAV 坐标)在图书馆检索并借阅(依赖)你的论文。mvn deploy(下一章)相当于你把论文发表到国际期刊(远程仓库),全世界的研究者都能引用。
install 的价值在于:打破项目孤岛,实现本地多项目协作。
图示
上图展示了 mvn install 的核心价值:项目 A 的 JAR 被安装到本地仓库后,项目 B 可以通过相同的 GAV 坐标声明依赖,Maven 自动从本地仓库解析并引入该 JAR。
完整示例
场景
飞翔科技有两个项目:
- 项目 A:
employee-system(员工管理系统)—— 提供核心领域模型和 Service - 项目 B:
payroll-service(薪资计算服务)—— 需要依赖项目 A 的Employee类和EmployeeService
架构师白歌要求:项目 B 必须在 pom.xml 中正常声明对项目 A 的依赖,而不是手动复制 JAR 文件。
操作前:项目状态
项目 A 的 pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.feixiang</groupId>
<artifactId>employee-system</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
</project>
项目 B 的 pom.xml(已声明对项目 A 的依赖):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.feixiang</groupId>
<artifactId>payroll-service</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>com.feixiang</groupId>
<artifactId>employee-system</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>
此时如果小崔在项目 B 中执行 mvn compile,会报错:
[ERROR] Failed to execute goal on project payroll-service:
Could not resolve dependencies for project com.feixiang:payroll-service:jar:1.0.0:
The following artifacts could not be resolved: com.feixiang:employee-system:jar:1.0.0
因为项目 A 的 JAR 还没有被安装到本地仓库,Maven 找不到这个依赖。
操作步骤
步骤一:在项目 A 中执行 install
cd employee-system
mvn clean install
步骤二:观察输出
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------< com.feixiang:employee-system >------------------
[INFO] Building employee-system 1.0.0
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
...
[INFO] --- jar:3.3.0:jar (default-jar) @ employee-system ---
[INFO] Building jar: C:\Users\xiaocui\workspace\employee-system\target\employee-system-1.0.0.jar
[INFO]
[INFO] --- install:3.1.1:install (default-install) @ employee-system ---
[INFO] Installing C:\Users\xiaocui\workspace\employee-system\target\employee-system-1.0.0.jar
to C:\Users\xiaocui\.m2\repository\com\feixiang\employee-system\1.0.0\employee-system-1.0.0.jar
[INFO] Installing C:\Users\xiaocui\workspace\employee-system\pom.xml
to C:\Users\xiaocui\.m2\repository\com\feixiang\employee-system\1.0.0\employee-system-1.0.0.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
关键输出解读:
install:3.1.1:install——maven-install-plugin执行安装Installing ... to ...—— JAR 和 POM 被复制到本地仓库的具体路径
install 后的本地仓库路径变化
install 前:
~/.m2/repository/
└── com/
└── feixiang/
└── (employee-system 目录不存在)
install 后:
~/.m2/repository/
└── com/
└── feixiang/
└── employee-system/
└── 1.0.0/
├── employee-system-1.0.0.jar
├── employee-system-1.0.0.pom
└── _remote.repositories
步骤三:在项目 B 中编译验证
cd ../payroll-service
mvn compile
输出:
[INFO] Scanning for projects...
[INFO]
[INFO] -------------------< com.feixiang:payroll-service >-------------------
[INFO] Building payroll-service 1.0.0
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- compiler:3.11.0:compile (default-compile) @ payroll-service ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 3 source files to target\classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
项目 B 编译成功,说明它已经从本地仓库成功解析并引入了项目 A 的依赖。
易错点与常见问题
误区一:install 会上传到远程仓库
错误认知:"我执行了 mvn install,公司的 Nexus 仓库里就有这个 JAR 了,同事能从公司仓库下载。"
纠正:mvn install 只安装到本地仓库(你电脑上的 ~/.m2/repository)。要让同事也能使用,需要执行 mvn deploy,将产物上传到远程仓库(如 Nexus、Artifactory)。deploy 需要配置远程仓库地址和认证信息,通常由 CI/CD 流水线(Jenkins)自动执行,不允许开发者本地直接 deploy。
误区二:install 后修改代码不需要重新 install
错误认知:"我 install 了项目 A,然后改了项目 A 的代码,项目 B 应该自动用到新代码。"
纠正:本地仓库中的 JAR 是静态快照。修改项目 A 的源码后,必须重新执行 mvn clean install,才能将新版本覆盖到本地仓库。否则项目 B 引用的仍然是旧版本的 JAR。
最佳实践:在多模块项目中,使用 mvn clean install 从父项目根目录一次性构建所有模块,避免逐个手动 install。
误区三:install 和 package 的产物不同
错误认知:"mvn install 生成的 JAR 和 mvn package 生成的 JAR 不一样,install 的更好。"
纠正:两个命令生成的 JAR 文件内容完全一致。install 只是将 package 阶段已经生成的 JAR 从 target/ 复制到本地仓库。如果你怀疑产物不同,可以用 diff 或 md5sum 验证——它们必然相同。
误区四:SNAPSHOT 版本 install 后不需要更新
典型问题:小崔将项目 A 的版本改为 1.0.0-SNAPSHOT 后 install,项目 B 引用了这个 SNAPSHOT,但过了几天项目 A 又更新了,项目 B 没有自动获取最新版。
纠正:SNAPSHOT 版本的设计初衷就是"频繁变化"。默认情况下,Maven 每天只检查一次远程仓库的 SNAPSHOT 更新。对于本地仓库中的 SNAPSHOT,Maven 不会自动刷新。解决方法是:
# 强制更新 SNAPSHOT 依赖
mvn clean compile -U
# 或在项目 B 的 pom.xml 中配置始终检查更新(仅限本地开发)
但最根本的解决方法是:修改项目 A 后,在项目 A 中重新执行 mvn clean install。
小结
mvn install 是 Maven 实现本地多项目协作的核心命令。它将 package 阶段生成的 JAR/WAR 安装到本地仓库(~/.m2/repository),使其他本地项目可以通过 GAV 坐标引用它。核心要点:
mvn install隐式执行compile→test→package→install- 产物按 GAV 坐标存储在本地仓库的层级目录中
- install 只操作本地仓库,不上传远程;远程上传需要
mvn deploy - 修改源码后必须重新 install,否则依赖方仍使用旧版本
- SNAPSHOT 版本需要显式重新 install 才能更新
本章与全局的关系:本章讲解了本地仓库安装。下一章 mvn dependency:tree 将带你学习如何查看和分析项目的依赖关系,排查依赖问题。