承接上篇 Maven 概述、IDEA 配置、项目创建与坐标,中篇依赖基础,本篇完整讲解依赖排除、依赖 scope 作用域、Maven 三套生命周期、JUnit5 全套单元测试、Maven 常见报错解决方案,内容详细,配套代码、表格、实操步骤,是 Maven 核心实操收尾章节。
一、高级依赖管理(排除依赖 + scope 依赖范围)
1.1 传递依赖冲突解决方案:exclusions 排除依赖
产生问题场景
项目 A 引入 spring-context,该包自动携带 micrometer 等无关依赖,会造成包冗余、版本冲突,需要手动剔除不需要的传递 jar。
完整 pom 配置语法
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.1.4</version>
<!-- 排除内部传递依赖 -->
<exclusions>
<exclusion>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-observation</artifactId>
</exclusion>
</exclusions>
</dependency>
关键注意点
<exclusion>内只需要写 groupId、artifactId,不需要 version;- 一个 dependency 下可写多个
<exclusion>,批量剔除多个传递包; - 修改 pom 后必须刷新 Maven 项目,配置才会生效。
1.2 scope 依赖作用范围(四大取值详细对照表)
scope 标签写在 dependency 内部,控制当前 jar 在主代码、测试代码、打包部署三个场景是否生效,是后端开发高频考点。
| scope 取值 | 作用于 main 业务代码 | 作用于 test 测试代码 | 是否参与打包上线 | 典型使用场景 |
|---|---|---|---|---|
| compile(默认) | ✅ 生效 | ✅ 生效 | ✅ 参与打包 | 工具类 hutool、spring 核心包 |
| test | ❌ 无效 | ✅ 生效 | ❌ 不打包 | JUnit 单元测试框架 |
| provided | ✅ 生效 | ✅ 生效 | ❌ 不打包 | servlet-api(服务器自带) |
| runtime | ❌ 编译期无效 | ✅ 生效 | ✅ 打包 | JDBC 数据库驱动 |
JUnit 标准 scope 配置示例
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.1</version>
<scope>test</scope>
</dependency>
核心理解
测试专用包只在 test 文件夹可用,打包发布时不会打进 jar 包,减小项目体积。
二、Maven 三套完整生命周期(底层插件机制)
2.1 生命周期核心概念
生命周期是 Maven 统一标准化的项目构建流程,每套生命周期互相独立,内部阶段有固定先后顺序;执行后序阶段,会自动前置执行前面所有阶段。三大独立生命周期:
- clean:清理生命周期(删除编译打包产物)
- default:核心构建生命周期(编译、测试、打包、安装,开发最常用)
- site:站点文档生命周期(企业文档生成,日常开发极少使用)
2.2 clean 生命周期
仅 3 个执行阶段,顺序:pre-clean → clean → post-clean
- clean 阶段核心功能:删除项目 target 目录(编译、打包生成的 class、jar 全部清除)执行命令:
mvn clean
2.3 default 默认核心生命周期(重点)
完整标准阶段,只记开发高频 5 个核心阶段:
- compile:编译 src/main/java 业务代码,生成 class 放入 target
- test:执行 src/test 下所有 JUnit 单元测试
- package:将编译后的 class、资源打包为 jar/war 包
- install:把当前项目 jar 安装到本地仓库,供本地其他项目依赖
- deploy:上传项目包到企业私服(公司内部项目使用)
执行规则:例如执行mvn package,会自动依次执行 validate → compile → test → package,前置步骤全部自动执行。
2.4 site 生命周期
用于生成项目说明文档、测试报告,自学阶段几乎不会用到,简单了解即可。
2.5 生命周期底层原理:插件绑定
Maven 本身无编译、测试能力,所有功能由插件实现,每个生命周期阶段预先绑定对应插件:
- compile 阶段绑定 maven-compiler-plugin 编译器插件
- test 绑定 maven-surefire-plugin 测试插件
- clean 绑定 maven-clean-plugin 清理插件
2.6 两种执行生命周期方式
-
IDEA 可视化操作:右侧 Maven 工具栏,双击对应阶段(clean/compile/package)
-
CMD 命令行执行:
mvn clean
mvn compile
mvn test
mvn package
mvn install
三、JUnit5 完整单元测试体系(重点实操)
3.1 软件测试四大分层
- 单元测试:测试单个方法,开发人员编写,白盒测试(看懂代码逻辑)
- 集成测试:多个模块组合测试,灰盒测试
- 系统测试:完整项目功能测试,测试人员黑盒测试
- 验收测试:客户业务验收,黑盒测试
3. JUnit 对比原生 main 方法优势
- 代码分离:测试代码统一放在 src/test,不污染业务 main 代码
- 独立运行:单个测试方法失败,不会阻断其他测试执行
- 可视化结果:绿色代表全部通过,红色代表用例失败
- 自动生成测试执行报告
3.2 JUnit 快速搭建完整流程
-
pom.xml 引入带
<scope>test的 JUnit 依赖; -
src/test/java 下创建测试类,命名规范
XxxTest; -
测试方法添加
@Test注解,方法要求:public void 无参数; -
右键运行测试类,查看红绿结果。基础测试代码示例:
import org.junit.jupiter.api.Test;
public class UserServiceTest {
@Test
public void testGetAge(){
// 业务方法调用
Integer age = new UserService().getAge("110002200505091218");
System.out.println(age);
}
}
3.3 断言 Assertions(单元测试核心,必写)
仅打印输出不代表代码正确,必须使用断言对比预期结果 和实际结果,不匹配直接抛出测试异常。完整常用断言对照表:
| 断言方法 | 功能说明 |
|---|---|
| assertEquals (预期,实际,提示信息) | 判断两个值相等,不等报错 |
| assertNotEquals (预期,实际) | 判断两个值不相等,相等报错 |
| assertNull (对象) | 对象为 null 则通过 |
| assertNotNull (对象) | 对象不为 null 则通过 |
| assertTrue (布尔表达式) | 表达式结果 true 通过 |
| assertFalse (布尔表达式) | 表达式结果 false 通过 |
| assertThrows (异常类,执行逻辑) | 校验方法是否抛出指定异常 |
带断言标准示例:
@Test
public void testGetGender(){
UserService service = new UserService();
String res = service.getGender("110002200505091218");
// 预期结果男,和实际对比
org.junit.jupiter.api.Assertions.assertEquals("男", res,"性别计算错误");
}
3.4 JUnit 全套核心注解详解
| 注解 | 作用 | 使用场景 |
|---|---|---|
| @Test | 标记普通测试方法 | 基础业务用例 |
| @BeforeEach | 每个测试方法执行前运行 | 每次初始化资源(创建对象、连接数据库) |
| @AfterEach | 每个测试执行后运行 | 释放资源、关闭连接 |
| @BeforeAll | 所有测试执行前运行,必须 static | 全局一次性初始化 |
| @AfterAll | 所有测试结束后运行,必须 static | 全局一次性销毁资源 |
| @DisplayName | 自定义测试类 / 方法展示名称 | 测试报告可读性优化 |
| @ParameterizedTest | 参数化测试 | 一组数据批量测同一个方法 |
| @ValueSource | 参数化数据源 | 提供多组测试入参 |
3.5 规范补充
测试代码禁止写在 src/main 目录,全部统一放到 src/test,遵循 Maven 标准目录规范。
四、Maven 常见报错完整解决方案
4.1 问题:依赖报红,jar 无法下载,仓库存在.lastUpdated文件
产生原因
网络中断、镜像超时,jar 包只下载一半,Maven 标记失败缓存,不会自动重试拉取。
分步解决办法
-
打开本地仓库目录,删除所有后缀
.lastUpdated的缓存文件; -
Windows 批量删除命令(CMD 执行):
del /s *.lastUpdated
-
IDEA 右侧 Maven 面板点击刷新按钮 Reload All Maven Projects;
-
刷新后仍报红:关闭 IDEA 软件,重新打开项目重新加载。
4.2 拓展常见小问题
- 项目路径含中文 / 空格:Maven 解析异常,项目移至纯英文路径;
- settings.xml 镜像配置写错:核对阿里云 mirror 标签完整结构;3 JDK 版本不匹配:IDEA 编译器统一和 Maven 使用 JDK 版本一致。
五、第三部分全文完整总结
- 依赖高级操作:
<exclusions>排除冲突传递依赖,scope 四大作用域区分打包范围; - Maven 生命周期分 clean、default、site 三套,default 是开发核心,执行后置阶段自动执行前置;
- 生命周期由插件实现,常用命令 clean/compile/test/package/install;
- JUnit 单元测试:test 目录存放、@Test 标识、断言校验结果;
- JUnit 注解:@BeforeEach/@AfterEach 实现资源初始化与释放;6 Maven 下载失败核心解决:删除 lastUpdated 缓存文件,刷新项目。
第三部分拓展实操练习
- 引入 spring 依赖,练习 exclusions 剔除无关传递包;
- 分别使用 mvn compile、mvn test、mvn package 命令观察 target 目录变化;
- 编写身份证解析工具类,使用 JUnit + 断言完成多组用例测试;
- 模拟网络中断产生 lastUpdated 文件,练习批量删除修复依赖报错。
第三部分面试高频考点
1 scope 四个取值区别,JUnit 为什么 scope 设为 test;2 传递依赖冲突如何使用 exclusions 排除;3 Maven default 生命周期核心阶段及执行顺序;4 单元测试为什么必须使用断言,只打印日志有什么缺陷;5 @BeforeEach 和 @BeforeAll 使用区别;6 Maven 依赖下载失败 lastUpdated 文件处理方案。
整套 Maven 三部分完整覆盖基础安装、IDEA 配置、依赖、生命周期、单元测试、报错处理,进阶内容(分模块、继承聚合、私服)属于 Maven 进阶章节,PPT 后续目录会单独讲解。
当前文件内容过长,豆包只阅读了前 46%。