Appearance
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/
核心作用:
- 方便的依赖管理
- 统一的项目结构
- 标准的项目构建流程
2.2 Maven 模型
Maven 包含三大核心模型:
- 项目对象模型(POM)
- 依赖管理模型(Dependency)
- 构建生命周期/阶段(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 包、插件)的目录,分为三类:
- 本地仓库:本地计算机上的目录,用于存储下载的依赖资源。
- 中央仓库:由 Maven 团队维护的全球唯一仓库,地址:https://repo1.maven.org/maven2/
- 远程仓库(私服):一般由公司团队搭建的私有仓库,用于内部资源共享。
依赖查找顺序:
- 默认:本地仓库 → 中央仓库
- 配置私服后:本地仓库 → 远程仓库 → 中央仓库
2.4 Maven 安装与配置
2.4.1 下载
下载地址:https://maven.apache.org/download.cgi,课程提供已下载的安装包 apache-maven-3.9.4-bin.zip。
2.4.2 安装步骤
- 解压安装:将安装包解压到无中文、无特殊字符的路径下(如
E:\develop)。解压后目录结构:
apache-maven-3.9.4
├── bin // 可执行命令(重点关注 mvn 命令)
├── boot // 启动相关文件
├── conf // 配置文件目录(重点关注 settings.xml)
├── lib // Maven 依赖的 jar 包
├── LICENSE // 许可证文件
├── NOTICE // 声明文件
└── README.txt // 说明文档配置本地仓库
- 新建本地仓库目录(如
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>- 新建本地仓库目录(如
配置阿里云私服
- 打开
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>- 打开
配置 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>- 在
配置环境变量
- 新建系统变量
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 全局设置
- 进入 IDEA 欢迎页面,选择
File → Close Project。 - 打开
All settings → Build,Execution,Deployment → Build Tools → Maven,配置以下信息:Maven home directory:Maven 解压目录。User settings file:选择conf/settings.xml文件,勾选Override。Local repository:本地仓库路径,勾选Override。
- 配置编译版本:进入
Build,Execution,Deployment → Compiler → Java Compiler,设置Target bytecode version为 21(或 20,根据 JDK 版本选择)。
3.2 创建 Maven 项目
- 新建空项目:
New Project → Empty Project,名称为web_project01,路径为D:\。 - 新建模块:右键项目 →
New → Module,选择Java → Maven,配置:Name:模块名(如maven-project01)。Location:模块路径。GroupId:组织名(如com.itheima)。ArtifactId:模块名(如maven-project01)。JDK:选择 JDK 21。
- 创建 HelloWorld 类:在
src/main/java/com/itheima目录下创建HelloWorld类,代码如下:
java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello Maven ...");
}
}- 运行:右键
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 坐标详解
坐标是资源的唯一标识,用于定位项目或依赖,由 groupId、artifactId、version 组成:
groupId:组织名称(如 com.itheima)。artifactId:项目/模块名称(如 maven-project01)。version:版本号(如 1.0-SNAPSHOT)。
3.4 导入 Maven 项目
方式 1
File → Project Structure → Modules → Import Module → 选择 Maven 项目的 pom.xml 文件。
方式 2
- 打开 Maven 面板:
View → Appearance → Tool Window Bars。 - 点击 Maven 面板的
+(Add Maven Projects),选择项目的 pom.xml 文件。
四、依赖管理
4.1 依赖配置
依赖指项目运行所需的 jar 包,配置步骤如下:
- 在 pom.xml 中添加
<dependencies>标签。 - 在
<dependencies>中使用<dependency>引入坐标(groupId、artifactId、version)。 - 点击 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 套相互独立的生命周期:
- clean:清理工作(如移除上一次构建生成的文件)。
- default:核心工作(如编译、测试、打包、安装、部署等)。
- site:生成报告、发布站点等。
4.3.2 核心生命周期阶段(常用)
clean:清理构建产物。compile:编译项目源代码。test:运行单元测试。package:打包编译后的文件(如 jar、war)。install:安装项目到本地仓库。
4.3.3 生命周期执行规则
- 同一生命周期内,执行后续阶段时,会自动执行前面所有阶段(如执行
package会先执行compile、test)。 - 不同生命周期相互独立(如执行
package不会执行clean)。
4.3.4 执行方式
- IDEA 中执行:右侧 Maven 工具栏 → 选择生命周期阶段 → 双击执行。
- 命令行执行:进入项目根目录(pom.xml 所在目录),执行
mvn 生命周期阶段(如mvn clean package)。
五、单元测试
5.1 测试概述
测试阶段划分
| 测试阶段 | 说明 | 测试人员 |
|---|---|---|
| 单元测试 | 测试最小功能单元(方法) | 开发人员 |
| 集成测试 | 测试单元间的协作 | 开发人员 |
| 系统测试 | 测试完整软件系统 | 测试人员 |
| 验收测试 | 验证是否满足用户需求 | 客户/需求方 |
测试方法
- 白盒测试:清楚软件内部结构和代码逻辑,验证逻辑正确性。
- 黑盒测试:不清楚内部结构,验证功能、兼容性等。
- 灰盒测试:结合白盒和黑盒测试特点。
5.2 JUnit 快速入门
JUnit 是 Java 常用单元测试框架,解决 main 方法测试的弊端(测试代码与源代码未分离、无法自动化、无测试报告)。
5.2.1 入门步骤
- 引入依赖:在 pom.xml 中添加 JUnit 依赖:
xml
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.1</version>
<scope>test</scope>
</dependency>- 创建测试类:在
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);
}
}- 运行测试:右键测试方法 → 选择
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(默认) | Y | Y | Y | log4j |
| test | Y | junit | ||
| provided | Y | Y | servlet-api | |
| runtime | Y | Y | jdbc 驱动 |
示例:JUnit 依赖配置 scope=test,表示仅在测试程序中可用,主程序无法使用。
六、Maven 常见问题
问题现象
Maven 依赖报红,重新加载后仍未下载。
产生原因
网络问题导致依赖下载不完整,本地仓库生成 xxx.lastUpdated 文件,该文件存在时不会重新下载。
解决方案
- 手动删除:根据依赖坐标找到本地仓库中对应的
xxx.lastUpdated文件,删除后重新加载项目。 - 批量删除:在本地仓库目录执行命令
del /s *.lastUpdated,递归删除所有xxx.lastUpdated文件,再重新加载项目。 - 重启 IDEA:若删除后仍报红,关闭 IDEA 重新打开项目。