Skip to content

Maven

一、初识 Maven

1.1 什么是 Maven?

Maven 是一款用于管理和构建 Java 项目的工具,是 Apache 旗下的一个开源项目。

Apache 软件基金会成立于 1999 年 7 月,是目前世界上最大且最受欢迎的开源软件基金会,也是一个专门为支持开源项目而生的非盈利性组织。开源项目列表可查看:https://www.apache.org/index.html#projects-list

1.2 Maven 的作用

Maven 主要有三大核心作用:依赖管理、项目构建、统一项目结构。

1.2.1 依赖管理

方便快捷地管理项目依赖的资源(jar 包),避免版本冲突问题。

  • 使用 Maven 前:需从官方网站下载 jar 包,手动导入项目中。项目结构示例:
common_project
├── lib
│   └── commons-io-2.11.0.jar
├── src
└── common_project.iml
  • 使用 Maven 后:只需在项目的 pom.xml 文件中添加依赖配置,Maven 会自动下载对应 jar 包并引入项目。配置示例:
xml
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>

1.2.2 项目构建

Maven 提供标准化的跨平台自动化构建方式,支持项目的编译(compile)、测试(test)、打包(package)、发布(deploy)等流程,通过简单命令即可完成,且兼容 Windows、Linux、MacOS 等系统。

1.2.3 统一项目结构

  • 未使用 Maven 时:不同开发工具(Eclipse、MyEclipse、IDEA)创建的 Java 项目目录结构存在差异,导致项目无法直接跨工具导入。
  • 使用 Maven 时:提供标准统一的项目结构,无论使用何种开发工具,基于 Maven 构建的项目目录结构一致,可直接跨工具导入使用。标准结构如下:
maven-project
├── src
│   ├── main
│   │   ├── java       // 源代码文件目录
│   │   └── resources  // 配置文件目录
│   └── test
│       ├── java       // 测试代码文件目录
│       └── resources  // 测试配置文件目录
└── pom.xml            // Maven 核心配置文件

总结:Maven 是一款管理和构建 Java 项目的工具,核心分为 Maven 核心和 Maven 进阶两部分,本文重点讲解核心内容。

二、Maven 概述

2.1 Maven 介绍

Apache Maven 是一个项目管理和构建工具,基于项目对象模型(Project Object Model,简称 POM)的概念,通过一小段描述信息来管理项目的构建、报告和文档。

官网地址:https://maven.apache.org/

核心作用:

  1. 方便的依赖管理
  2. 统一的项目结构
  3. 标准的项目构建流程

2.2 Maven 模型

Maven 包含三大核心模型:

  1. 项目对象模型(POM)
  2. 依赖管理模型(Dependency)
  3. 构建生命周期/阶段(Build lifecycle & phases)

1) 构建生命周期/阶段

Maven 定义了标准化的构建流程(如编译、测试、打包等),每个阶段由对应的插件实现。例如:编译阶段使用编译插件,打包阶段使用打包插件。

2) 项目对象模型(POM)

将项目抽象为对象模型,通过 pom.xml 文件描述项目信息,核心是项目坐标(groupId、artifactId、version),坐标是资源(jar 包、项目)的唯一标识,可用于定位项目或依赖。

pom.xml 基础配置示例:

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">
    <!-- POM 模型版本 -->
    <modelVersion>4.0.0</modelVersion>
    <!-- 项目坐标 -->
    <groupId>com.itheima</groupId>
    <artifactId>maven-project01</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!-- 打包方式(默认 jar,Web 项目常用 war) -->
    <packaging>jar</packaging>
</project>

3) 依赖管理模型(Dependency)

通过坐标描述项目依赖的第三方 jar 包,配置在 pom.xml 的 <dependencies> 标签中。Maven 会根据坐标自动查找并引入依赖的 jar 包。

2.3 Maven 仓库

仓库是用于存储资源(jar 包、插件)的目录,分为三类:

  1. 本地仓库:本地计算机上的目录,用于存储下载的依赖资源。
  2. 中央仓库:由 Maven 团队维护的全球唯一仓库,地址:https://repo1.maven.org/maven2/
  3. 远程仓库(私服):一般由公司团队搭建的私有仓库,用于内部资源共享。

依赖查找顺序

  • 默认:本地仓库 → 中央仓库
  • 配置私服后:本地仓库 → 远程仓库 → 中央仓库

2.4 Maven 安装与配置

2.4.1 下载

下载地址:https://maven.apache.org/download.cgi,课程提供已下载的安装包 apache-maven-3.9.4-bin.zip

2.4.2 安装步骤

  1. 解压安装:将安装包解压到无中文、无特殊字符的路径下(如 E:\develop)。解压后目录结构:
apache-maven-3.9.4
├── bin        // 可执行命令(重点关注 mvn 命令)
├── boot       // 启动相关文件
├── conf       // 配置文件目录(重点关注 settings.xml)
├── lib        // Maven 依赖的 jar 包
├── LICENSE    // 许可证文件
├── NOTICE     // 声明文件
└── README.txt // 说明文档
  1. 配置本地仓库

    • 新建本地仓库目录(如 D:\develop\apache-maven-3.9.4\mvn_repo)。
    • 打开 conf/settings.xml 文件,定位到 53 行,复制 <localRepository> 标签到注释外,替换为本地仓库路径:
    xml
    <localRepository>D:\develop\apache-maven-3.9.4\mvn_repo</localRepository>
  2. 配置阿里云私服

    • 打开 conf/settings.xml 文件,定位到 160 行左右,在 <mirrors> 标签中添加阿里云镜像配置:
    xml
    <mirror>
        <id>alimaven</id>
        <name>aliyun maven</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        <mirrorOf>central</mirrorOf>
    </mirror>
  3. 配置 JDK 版本

    • conf/settings.xml<profiles> 标签中添加 JDK 21 配置:
    xml
    <profile>
        <id>jdk-21</id>
        <activation>
            <activeByDefault>true</activeByDefault>
            <jdk>21</jdk>
        </activation>
        <properties>
            <maven.compiler.source>21</maven.compiler.source>
            <maven.compiler.target>21</maven.compiler.target>
            <maven.compiler.compilerVersion>21</maven.compiler.compilerVersion>
        </properties>
    </profile>
  4. 配置环境变量

    • 新建系统变量 MAVEN_HOME,值为 Maven 解压目录(如 D:\develop\apache-maven-3.9.4)。
    • 在系统变量 Path 中添加 %MAVEN_HOME%\bin
    • 验证:打开 DOS 命令行,输入 mvn -v,显示 Maven 版本信息则安装成功。

三、IDEA 集成 Maven

3.1 配置 Maven 环境

3.1.1 全局设置

  1. 进入 IDEA 欢迎页面,选择 File → Close Project
  2. 打开 All settings → Build,Execution,Deployment → Build Tools → Maven,配置以下信息:
    • Maven home directory:Maven 解压目录。
    • User settings file:选择 conf/settings.xml 文件,勾选 Override
    • Local repository:本地仓库路径,勾选 Override
  3. 配置编译版本:进入 Build,Execution,Deployment → Compiler → Java Compiler,设置 Target bytecode version 为 21(或 20,根据 JDK 版本选择)。

3.2 创建 Maven 项目

  1. 新建空项目:New Project → Empty Project,名称为 web_project01,路径为 D:\
  2. 新建模块:右键项目 → New → Module,选择 Java → Maven,配置:
    • Name:模块名(如 maven-project01)。
    • Location:模块路径。
    • GroupId:组织名(如 com.itheima)。
    • ArtifactId:模块名(如 maven-project01)。
    • JDK:选择 JDK 21。
  3. 创建 HelloWorld 类:在 src/main/java/com/itheima 目录下创建 HelloWorld 类,代码如下:
java
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello Maven ...");
    }
}
  1. 运行:右键 main 方法,选择 Run HelloWorld,输出 Hello Maven ... 则成功。

3.3 POM 配置详解

3.3.1 POM 核心标签

标签说明
<project>pom.xml 根标签,描述 Maven 项目
<modelVersion>POM 模型版本(当前为 4.0.0)
<groupId>组织名称(域名反写,如 com.itheima)
<artifactId>项目/模块名称
<version>版本号(SNAPSHOT 为快照版,RELEASE 为稳定版)
<packaging>打包方式(jar 或 war,默认 jar)

3.3.2 Maven 坐标详解

坐标是资源的唯一标识,用于定位项目或依赖,由 groupIdartifactIdversion 组成:

  • groupId:组织名称(如 com.itheima)。
  • artifactId:项目/模块名称(如 maven-project01)。
  • version:版本号(如 1.0-SNAPSHOT)。

3.4 导入 Maven 项目

方式 1

File → Project Structure → Modules → Import Module → 选择 Maven 项目的 pom.xml 文件

方式 2

  1. 打开 Maven 面板:View → Appearance → Tool Window Bars
  2. 点击 Maven 面板的 +(Add Maven Projects),选择项目的 pom.xml 文件。

四、依赖管理

4.1 依赖配置

依赖指项目运行所需的 jar 包,配置步骤如下:

  1. 在 pom.xml 中添加 <dependencies> 标签。
  2. <dependencies> 中使用 <dependency> 引入坐标(groupId、artifactId、version)。
  3. 点击 IDEA 中 pom.xml 文件的刷新按钮,加载依赖。

配置示例:

xml
<dependencies>
    <!-- commons-io 依赖 -->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.11.0</version>
    </dependency>
</dependencies>

注意事项

  • 若本地仓库无该依赖,Maven 会自动从远程仓库/中央仓库下载。
  • 未知坐标可通过 Maven 中央仓库 搜索。
  • 快速添加依赖:在 pom.xml 中按 Alt+Insert,选择 Dependency 搜索添加。

4.2 依赖传递

4.2.1 依赖传递规则

Maven 依赖具有传递性,无需手动导入间接依赖的 jar 包:

  • 直接依赖:项目中直接配置的依赖(如 A 依赖 B)。
  • 间接依赖:被依赖资源的依赖(如 B 依赖 C,则 A 间接依赖 C)。

4.2.2 排除依赖

若需断开间接依赖(如 A 依赖 B,B 依赖 C,但 A 不需要 C),可通过 <exclusions> 标签排除,无需指定版本:

xml
<dependency>
    <groupId>com.itheima</groupId>
    <artifactId>maven-projectB</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!-- 排除 junit 依赖 -->
    <exclusions>
        <exclusion>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </exclusion>
    </exclusions>
</dependency>

4.3 生命周期

4.3.1 生命周期分类

Maven 定义了 3 套相互独立的生命周期:

  1. clean:清理工作(如移除上一次构建生成的文件)。
  2. default:核心工作(如编译、测试、打包、安装、部署等)。
  3. site:生成报告、发布站点等。

4.3.2 核心生命周期阶段(常用)

  • clean:清理构建产物。
  • compile:编译项目源代码。
  • test:运行单元测试。
  • package:打包编译后的文件(如 jar、war)。
  • install:安装项目到本地仓库。

4.3.3 生命周期执行规则

  • 同一生命周期内,执行后续阶段时,会自动执行前面所有阶段(如执行 package 会先执行 compiletest)。
  • 不同生命周期相互独立(如执行 package 不会执行 clean)。

4.3.4 执行方式

  1. IDEA 中执行:右侧 Maven 工具栏 → 选择生命周期阶段 → 双击执行。
  2. 命令行执行:进入项目根目录(pom.xml 所在目录),执行 mvn 生命周期阶段(如 mvn clean package)。

五、单元测试

5.1 测试概述

测试阶段划分

测试阶段说明测试人员
单元测试测试最小功能单元(方法)开发人员
集成测试测试单元间的协作开发人员
系统测试测试完整软件系统测试人员
验收测试验证是否满足用户需求客户/需求方

测试方法

  • 白盒测试:清楚软件内部结构和代码逻辑,验证逻辑正确性。
  • 黑盒测试:不清楚内部结构,验证功能、兼容性等。
  • 灰盒测试:结合白盒和黑盒测试特点。

5.2 JUnit 快速入门

JUnit 是 Java 常用单元测试框架,解决 main 方法测试的弊端(测试代码与源代码未分离、无法自动化、无测试报告)。

5.2.1 入门步骤

  1. 引入依赖:在 pom.xml 中添加 JUnit 依赖:
xml
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.9.1</version>
    <scope>test</scope>
</dependency>
  1. 创建测试类:在 src/test/java 目录下创建测试类(命名规范:XxxxTest),编写测试方法(命名规范:public void xxx()),并添加 @Test 注解。

示例:

java
import org.junit.jupiter.api.Test;

public class UserServiceTest {
    @Test
    public void testGetAge() {
        Integer age = new UserService().getAge("110002200505091218");
        System.out.println(age);
    }
}
  1. 运行测试:右键测试方法 → 选择 Run,绿色表示测试通过,红色表示失败。

5.3 JUnit 常见注解

注解说明备注
@Test标识测试方法单元测试核心注解
@BeforeEach每个测试方法执行前执行一次初始化资源
@AfterEach每个测试方法执行后执行一次释放资源
@BeforeAll所有测试方法执行前执行一次静态方法,初始化资源
@AfterAll所有测试方法执行后执行一次静态方法,释放资源
@ParameterizedTest参数化测试,单个测试多次运行无需 @Test 注解
@ValueSource为参数化测试提供参数@ParameterizedTest 配合使用
@DisplayName指定测试类/方法的显示名称增强可读性

注解示例:

java
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

@DisplayName("测试-学生业务操作")
public class UserServiceTest {
    @BeforeAll
    public static void testBeforeAll() {
        System.out.println("before all ...");
    }

    @BeforeEach
    public void testBefore() {
        System.out.println("before...");
    }

    @DisplayName("测试-获取年龄")
    @Test
    public void testGetAge() {
        Integer age = new UserService().getAge("110002200505091218");
        System.out.println(age);
    }

    @DisplayName("测试-获取性别")
    @ParameterizedTest
    @ValueSource(strings = {"612429198904201611", "612429198904201631"})
    public void testGetGender(String idcard) {
        String gender = new UserService().getGender(idcard);
        System.out.println(gender);
    }

    @AfterEach
    public void testAfter() {
        System.out.println("after...");
    }

    @AfterAll
    public static void testAfterAll() {
        System.out.println("after all...");
    }
}

5.4 断言

断言用于验证方法执行结果是否符合预期,JUnit 提供常用断言方法:

断言方法描述
assertEquals(exp, act, msg)检查两个值是否相等,不相等则报错
assertNotEquals(unexp, act, msg)检查两个值是否不相等,相等则报错
assertNull(act, msg)检查对象是否为 null,不为 null 则报错
assertNotNull(act, msg)检查对象是否不为 null,为 null 则报错
assertTrue(condition, msg)检查条件是否为 true,不为 true 则报错
assertFalse(condition, msg)检查条件是否为 false,不为 false 则报错
assertSame(exp, act, msg)检查两个对象引用是否相等,不相等则报错

断言示例:

java
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class UserServiceTest {
    @Test
    public void testGetGender() {
        String gender = new UserService().getGender("612429198904201611");
        Assertions.assertEquals("男", gender, "性别匹配失败");
    }
}

5.5 依赖范围(scope)

通过 <scope> 标签限制依赖的使用范围,常用取值:

scope 值主程序(main)测试程序(test)打包(运行)示例
compile(默认)YYYlog4j
testYjunit
providedYYservlet-api
runtimeYYjdbc 驱动

示例:JUnit 依赖配置 scope=test,表示仅在测试程序中可用,主程序无法使用。

六、Maven 常见问题

问题现象

Maven 依赖报红,重新加载后仍未下载。

产生原因

网络问题导致依赖下载不完整,本地仓库生成 xxx.lastUpdated 文件,该文件存在时不会重新下载。

解决方案

  1. 手动删除:根据依赖坐标找到本地仓库中对应的 xxx.lastUpdated 文件,删除后重新加载项目。
  2. 批量删除:在本地仓库目录执行命令 del /s *.lastUpdated,递归删除所有 xxx.lastUpdated 文件,再重新加载项目。
  3. 重启 IDEA:若删除后仍报红,关闭 IDEA 重新打开项目。