Maven 基础教程(第三部分・完整版)

承接上篇 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>

关键注意点

  1. <exclusion>只需要写 groupId、artifactId,不需要 version
  2. 一个 dependency 下可写多个<exclusion>,批量剔除多个传递包;
  3. 修改 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 统一标准化的项目构建流程,每套生命周期互相独立,内部阶段有固定先后顺序;执行后序阶段,会自动前置执行前面所有阶段。三大独立生命周期:

  1. clean:清理生命周期(删除编译打包产物)
  2. default:核心构建生命周期(编译、测试、打包、安装,开发最常用)
  3. site:站点文档生命周期(企业文档生成,日常开发极少使用)

2.2 clean 生命周期

仅 3 个执行阶段,顺序:pre-clean → clean → post-clean

  • clean 阶段核心功能:删除项目 target 目录(编译、打包生成的 class、jar 全部清除)执行命令:mvn clean

2.3 default 默认核心生命周期(重点)

完整标准阶段,只记开发高频 5 个核心阶段:

  1. compile:编译 src/main/java 业务代码,生成 class 放入 target
  2. test:执行 src/test 下所有 JUnit 单元测试
  3. package:将编译后的 class、资源打包为 jar/war 包
  4. install:把当前项目 jar 安装到本地仓库,供本地其他项目依赖
  5. 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 两种执行生命周期方式

  1. IDEA 可视化操作:右侧 Maven 工具栏,双击对应阶段(clean/compile/package)

  2. CMD 命令行执行:

    mvn clean
    mvn compile
    mvn test
    mvn package
    mvn install

三、JUnit5 完整单元测试体系(重点实操)

3.1 软件测试四大分层

  1. 单元测试:测试单个方法,开发人员编写,白盒测试(看懂代码逻辑)
  2. 集成测试:多个模块组合测试,灰盒测试
  3. 系统测试:完整项目功能测试,测试人员黑盒测试
  4. 验收测试:客户业务验收,黑盒测试

3. JUnit 对比原生 main 方法优势

  1. 代码分离:测试代码统一放在 src/test,不污染业务 main 代码
  2. 独立运行:单个测试方法失败,不会阻断其他测试执行
  3. 可视化结果:绿色代表全部通过,红色代表用例失败
  4. 自动生成测试执行报告

3.2 JUnit 快速搭建完整流程

  1. pom.xml 引入带<scope>test的 JUnit 依赖;

  2. src/test/java 下创建测试类,命名规范XxxTest

  3. 测试方法添加@Test注解,方法要求:public void 无参数;

  4. 右键运行测试类,查看红绿结果。基础测试代码示例:

    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 标记失败缓存,不会自动重试拉取。

分步解决办法

  1. 打开本地仓库目录,删除所有后缀.lastUpdated的缓存文件;

  2. Windows 批量删除命令(CMD 执行):

    del /s *.lastUpdated

  3. IDEA 右侧 Maven 面板点击刷新按钮 Reload All Maven Projects;

  4. 刷新后仍报红:关闭 IDEA 软件,重新打开项目重新加载。

4.2 拓展常见小问题

  1. 项目路径含中文 / 空格:Maven 解析异常,项目移至纯英文路径;
  2. settings.xml 镜像配置写错:核对阿里云 mirror 标签完整结构;3 JDK 版本不匹配:IDEA 编译器统一和 Maven 使用 JDK 版本一致。

五、第三部分全文完整总结

  1. 依赖高级操作:<exclusions>排除冲突传递依赖,scope 四大作用域区分打包范围;
  2. Maven 生命周期分 clean、default、site 三套,default 是开发核心,执行后置阶段自动执行前置;
  3. 生命周期由插件实现,常用命令 clean/compile/test/package/install;
  4. JUnit 单元测试:test 目录存放、@Test 标识、断言校验结果;
  5. JUnit 注解:@BeforeEach/@AfterEach 实现资源初始化与释放;6 Maven 下载失败核心解决:删除 lastUpdated 缓存文件,刷新项目。

第三部分拓展实操练习

  1. 引入 spring 依赖,练习 exclusions 剔除无关传递包;
  2. 分别使用 mvn compile、mvn test、mvn package 命令观察 target 目录变化;
  3. 编写身份证解析工具类,使用 JUnit + 断言完成多组用例测试;
  4. 模拟网络中断产生 lastUpdated 文件,练习批量删除修复依赖报错。

第三部分面试高频考点

1 scope 四个取值区别,JUnit 为什么 scope 设为 test;2 传递依赖冲突如何使用 exclusions 排除;3 Maven default 生命周期核心阶段及执行顺序;4 单元测试为什么必须使用断言,只打印日志有什么缺陷;5 @BeforeEach 和 @BeforeAll 使用区别;6 Maven 依赖下载失败 lastUpdated 文件处理方案。

整套 Maven 三部分完整覆盖基础安装、IDEA 配置、依赖、生命周期、单元测试、报错处理,进阶内容(分模块、继承聚合、私服)属于 Maven 进阶章节,PPT 后续目录会单独讲解。

当前文件内容过长,豆包只阅读了前 46%。