1. Maven是什么?
基本概念
Maven是Apache基金会的开源项目管理和构建自动化工具,使用POM(Project Object Model) 文件描述项目结构、依赖关系和构建配置。是否专门用于Java?
主要定位:主要用于Java项目
可扩展性:通过插件可支持其他语言(Scala、Groovy、Kotlin等)
生态系统:虽然不限于Java,但在Java生态中最为成熟核心功能
1
2
3
4
5├── 依赖管理(Dependency Management)
├── 项目构建(Build Lifecycle)
├── 统一项目结构(Standard Directory Layout)
├── 插件体系(Plugin Architecture)
└── 仓库管理(Repository)Maven依赖的本质
- 通过pom.xml引入的依赖,默认下载的是已编译的JAR包,主要包含:
内容 说明 是否必须 .class文件 已编译的字节码(人类可读的.java源代码文件编译而来) ✅ 必须,用于运行 pom.xml 依赖的元数据 ✅ 必须,用于传递依赖解析 源代码(.java) 可选,用于调试 ❌ 可选,IDE可单独下载 javadoc API文档 ❌ 可选,IDE可单独下载 - 依赖获取过程
1
2
3
4
5
6// pom.xml中的依赖声明
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency> - 实际下载的文件
1
2
3
4
5
6
7~/.m2/repository/com/google/guava/guava/31.1-jre/
├── guava-31.1-jre.jar // 主要JAR,包含.class文件
├── guava-31.1-jre.pom // 该依赖的pom文件
├── _remote.repositories // 仓库信息
└── 可能还有:
├── guava-31.1-jre-sources.jar // 源代码
└── guava-31.1-jre-javadoc.jar // 文档
- 通过pom.xml引入的依赖,默认下载的是已编译的JAR包,主要包含:
2. Maven基本命令
常用命令速查表
| 命令 | 功能 | 说明 |
|---|---|---|
| mvn clean | 清理项目 | 删除target目录 |
| mvn compile | 编译源码 | 生成target/classes |
| mvn test | 运行测试 | 执行src/test下的测试 |
| mvn package | 打包项目 | 生成jar/war包 |
| mvn install | 安装到本地仓库 | mvn package + 将jar安装到本地 ~/.m2/repository |
| mvn deploy | 部署到远程仓库 | 发布到Nexus/Artifactory |
| mvn clean install | 清理并安装 | 常用组合命令 |
| mvn dependency:tree | 查看依赖树 | 分析依赖关系 |
| mvn spring-boot:run | 运行Spring Boot | 需要对应插件 |
Maven生命周期阶段
A[clean] –> B[validate] –> C[compile] –> D[test] –> E[package] –> F[verify] –> G[install] –> H[deploy]
1. mvn compile - 编译阶段
相当于:执行 javac 编译源代码
1 | # 实际操作 |
当您运行 mvn compile时,Maven 会:
解析依赖:读取 pom.xml 中的
下载依赖:从远程仓库下载到本地 ~/.m2/repository/
构建依赖图:处理传递依赖
关键点:Maven 管理的这些依赖是已经编译好的 .class 文件(JAR 包),不是 .java 文件。
然后 Maven 会:
编译您的代码:src/main/java/下的 .java 文件
使用依赖:编译时将下载的依赖 JAR 加入 classpath
打包:将您的 .class 文件 + 资源文件打包
todo:那么打包的时候到底保护包含依赖?我自己的源代码编译 .class + 依赖包的 .class ??
2. mvn package - 打包阶段
相当于:根据packaging类型不同,将编译结果打包成可分发的格式(注意:普通mvn package生成的jar不包含依赖!依赖需要单独配置)
1 | <!-- pom.xml中指定打包类型 --> |
打包过程:
1 | # 对于jar包: |
3. mvn install - 安装阶段
mvn install 做了两件事:
1 执行之前所有阶段:validate → compile → test → package → verify → install
2 将当前项目的构建结果安装到本地仓库,安装位置 →
1 | ~/.m2/repository/com/yourcompany/yourapp/1.0.0/ |
命令组合示例
1 | # 标准开发流程 |
3. 打包Java服务为可运行JAR
三种打包方式对比
| 方式 | 插件 | 特点 | 适用场景 |
|---|---|---|---|
| 普通JAR | maven-jar-plugin | 不包含依赖 | 库项目 |
| Fat JAR | maven-assembly-plugin | 包含所有依赖 | 简单应用 |
| 可执行JAR | spring-boot-maven-plugin | Spring Boot专用 | Spring Boot应用 |
| Shadow JAR | maven-shade-plugin | 重命名包解决冲突 | 复杂依赖 |
Spring Boot项目(最常用)
1 | <!-- pom.xml --> |
1 | # 打包命令 |
完整构建流程示例
项目结构
1 | my-project/ |
执行流程
1 | # 1. 清理 + 编译 |
4. IDEA中使用Maven与问题解决
IDEA Maven配置位置
1 | File → Settings → Build, Execution, Deployment → Build Tools → Maven |
常用操作
- 刷新依赖:Maven工具窗口的刷新按钮 🔄
- 执行命令:双击生命周期中的阶段
- 查看依赖图:右键项目 → Show Dependencies
- 排除冲突:在依赖树上右键排除
问题分类
- Import报红
本地仓库缺失
版本冲突
网络问题 - 编译失败
依赖下载不全
编译版本不匹配 - 运行时异常
依赖冲突
ClassNotFound
解决方案
- 点击刷新按钮
- 仍未解决,检查网络–> 清除本地仓库–> 清理IDEA缓存 –> 检查依赖冲突 –> 重新导入项目
具体问题解决步骤
问题1:刷新按钮无效
症状:点击刷新后,依赖仍然报红
解决方案:
强制刷新:
1
2# 命令行执行
mvn clean install -U-U参数强制更新快照版本删除本地仓库:
1
2
3
4
5# Windows
rd /s /q %USERPROFILE%\.m2\repository
# Mac/Linux
rm -rf ~/.m2/repository清除IDEA缓存:
1
File → Invalidate Caches and Restart
问题2:依赖下载慢/失败
解决方案:
配置阿里云镜像(
settings.xml):1
2
3
4
5
6
7
8<mirrors>
<mirror>
<id>aliyun</id>
<name>aliyun maven</name>
<url>https://maven.aliyun.com/repository/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>IDEA配置镜像:
1
2File → Settings → Build Tools → Maven
修改 User settings file 为包含镜像的settings.xml
问题3:依赖冲突
症状:NoSuchMethodError, ClassNotFoundException
排查命令:
1 | # 查看依赖树 |
IDEA可视化排查:
- 右键项目 → Analyze → Analyze Dependencies
- 查看冲突标记(红色)
解决冲突示例:
1 | <dependency> |
问题4:版本不兼容
1 | <!-- 统一管理版本 --> |
IDEA Maven工具窗口使用技巧
1. 快速操作
| 图标 | 功能 | 快捷键 |
|---|---|---|
| 🔄 | 重新导入所有Maven项目 | Ctrl+Shift+O |
| 🏃 | 运行Maven目标 | 右键→Run Maven |
| 📊 | 显示依赖图 | 右键→Show Dependencies |
| 🧹 | 执行clean | 双击Lifecycle→clean |
2. 配置文件切换
1 | <!-- pom.xml 中定义不同环境 --> |
在IDEA Maven工具窗口的Profiles中勾选激活。
终极解决方案清单
当遇到顽固依赖问题时,按顺序执行:
第一步:清理缓存
1
mvn clean install -U
第二步:删除本地仓库对应目录
1
2# 删除有问题依赖的目录
rm -rf ~/.m2/repository/com/example/problem-dependency第三步:IDEA完全清理
- File → Invalidate Caches and Restart
- 删除项目下的
.idea目录和*.iml文件 - 重新导入
第四步:检查Maven配置
1
2
3
4
5# 查看有效POM
mvn help:effective-pom
# 查看有效设置
mvn help:effective-settings第五步:网络代理检查
1
2
3
4
5
6
7
8
9
10<!-- settings.xml 配置代理 -->
<proxies>
<proxy>
<id>optional</id>
<active>true</active>
<protocol>http</protocol>
<host>proxy.company.com</host>
<port>8080</port>
</proxy>
</proxies>
预防措施
使用依赖锁定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>enforce</id>
<configuration>
<rules>
<dependencyConvergence/>
</rules>
</configuration>
<goals>
<goal>enforce</goal>
</goals>
</execution>
</executions>
</plugin>定期清理本地仓库
1
2# 清理失败下载
find ~/.m2/repository -name "*.lastUpdated" -delete使用CI/CD环境验证
在Jenkins/GitHub Actions中设置定期构建,提前发现问题。
常见错误代码与解决
| 错误代码 | 含义 | 解决方案 |
|---|---|---|
| 501 HTTPS Required | 仓库需要HTTPS | 更新settings.xml,使用https仓库 |
| 401 Unauthorized | 认证失败 | 配置正确的server认证 |
| Could not transfer artifact | 网络/权限 | 检查网络,清理.lastUpdated文件 |
| No compiler is provided | JDK配置错误 | 配置JAVA_HOME,或在pom中指定javac |
高级技巧
离线模式(网络不稳定时)
1
mvn clean install -o
跳过测试
1
2
3mvn clean install -DskipTests
# 或
mvn clean install -Dmaven.test.skip=true多线程构建
1
mvn clean install -T 4
调试模式
1
mvn -X clean install