【学习总结|DAY024】Maven基础
一、引言
在 Java 项目开发中,Maven 是一款至关重要的工具,它能够极大地提升项目管理与构建的效率。本文将详细介绍 Maven 的核心概念、安装配置、在 IDEA 中的集成应用、依赖管理、项目构建生命周期、单元测试以及常见问题的解决方法,并结合实际代码示例进行说明。
二、Maven 概述
(一)定义与作用
Maven 是 apache 旗下的开源项目管理和构建工具,基于项目对象模型(POM),可实现标准化、跨平台(Linux、Windows、MacOS)的自动化项目构建,提供统一项目结构,并方便管理项目依赖的资源(jar 包)。
(二)仓库类型
- 本地仓库:位于本地计算机的特定目录,用于存储已下载的 jar 包,如
D:\develop\apache-maven-3.9.4\mvn_repo
。 - 中央仓库:由 Maven 团队维护的全球唯一仓库,地址为
https://repo1.maven.org/maven2/
。 - 远程仓库(私服):通常由公司团队搭建,用于存储内部或特定的 jar 包资源。
查找依赖(jar)时,先在本地仓库查找,若不存在则依次从远程仓库、中央仓库获取。
三、Maven 安装
- 解压
apache-maven-3.9.4-bin.zip
文件。 - 配置本地仓库:在
conf/settings.xml
中修改<localRepository>
标签为指定目录,如<localRepository>D:\develop\apache-maven-3.9.4\mvn_repo</localRepository>
。 - 配置阿里云私服:在
conf/settings.xml
的<mirrors>
标签内添加如下子标签,以加快依赖下载速度。
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
- 配置环境变量:设置
MAVEN_HOME
为 maven 解压目录,并将其bin
目录添加到PATH
环境变量。
安装完成后,在命令行输入 mvn -v
可查看 Maven 版本信息,验证安装是否成功。
四、IDEA 集成 Maven
(一)配置 Maven 环境(全局)
在 IDEA 中,依次点击 Settings
-> Build, Execution, Deployment
-> Build Tools
-> Maven
,设置 Maven home path
为安装目录,User settings file
为 conf/settings.xml
,Local repository
为本地仓库目录。同时,可在 Runner
选项卡中配置相关运行参数。
(二)创建 Maven 项目
选择 New Module
,填写模块信息,构建工具选择 Maven
,指定 GroupId
(如 com.itheima
)、ArtifactId
(如 maven-project01
)和 Version
(如 1.0-SNAPSHOT
)等信息后点击 create
即可创建项目。创建完成后,可在项目的 pom.xml
文件中进一步配置项目信息和依赖。
例如,以下是一个简单的 pom.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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itheima</groupId>
<artifactId>maven-project01</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- 引入 hutool-all 依赖 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.27</version>
</dependency>
</dependencies>
</project>
(三)导入 Maven 项目
- 方式一:
File
->Project Structure
->Modules
->Import Module
-> 选择 maven 项目的pom.xml
。 - 方式二:通过
Maven
面板 ->+
(Add Maven Projects
) -> 选择pom.xml
。建议先将项目复制到本地目录后再进行导入操作。
五、依赖管理
(一)依赖配置
在 pom.xml
中,使用 <dependencies>
标签包裹 <dependency>
标签来引入依赖。每个 <dependency>
标签需指定 groupId
、artifactId
和 version
。例如,引入 spring-context
依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.1.4</version>
</dependency>
若引入的依赖在本地仓库不存在,Maven 会自动从远程仓库或中央仓库下载。若不知道依赖坐标,可在 https://mvnrepository.com/
搜索。
(二)排除依赖
有时需要排除某些依赖,可在 <dependency>
标签内使用 <exclusions>
标签。例如,排除 spring-context
依赖中的 micrometer-observation
:
<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>
(三)依赖范围
依赖的 jar
包默认在任何地方可用,可通过 <scope>
标签设置作用范围,常见取值如下:
scope 值 | 主程序 | 测试程序 | 打包(运行) | 范例 |
---|---|---|---|---|
compile(默认) | Y | Y | Y | log4j |
test | - | Y | - | junit |
provided | Y | Y | - | servlet-api |
runtime | - | Y | Y | jdbc 驱动 |
例如,将 junit-jupiter
依赖设置为仅在测试程序范围有效:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.3</version>
<scope>test</scope>
</dependency>
六、项目构建生命周期
Maven 有 3 套相互独立的生命周期:clean
、default
和 site
。
- clean:主要用于清理上一次构建生成的文件,包含
pre-clean
、clean
、post-clean
等阶段。 - default:是核心生命周期,涵盖编译、测试、打包、安装、部署等操作,具体阶段如下:
validate
:验证项目是否正确,以及所有必要信息是否可用。initialize
:初始化构建状态。generate-sources
:生成包含在编译阶段中的任何源代码。process-sources
:处理源代码,例如过滤一些值。generate-resources
:生成资源文件并复制到输出目录。process-resources
:复制并处理资源文件至目标目录,准备打包。compile
:编译项目的源代码。process-classes
:对编译后的类文件进行后处理。generate-test-sources
:生成测试用的源代码。process-test-sources
:处理测试源代码。generate-test-resources
:生成测试资源文件并复制到测试输出目录。process-test-resources
:复制并处理测试资源文件至测试目标目录。test-compile
:编译测试源代码。process-test-classes
:对测试编译后的类文件进行后处理。test
:使用合适的单元测试框架运行测试。prepare-package
:在实际打包之前执行一些准备工作。package
:将编译后的文件打包成可分发的格式,如jar
、war
等。verify
:对打包后的文件进行验证,确保其符合质量标准。install
:将项目安装到本地仓库,以便其他项目可以引用。deploy
:将项目部署到远程仓库,供其他开发人员或项目使用。
- site:用于生成项目报告、发布站点等,包含
pre-site
、site
、post-site
、site-deploy
等阶段。
在同一套生命周期中,运行后面的阶段时,前面的阶段会自动依次执行。可在 IDEA 的 Maven 工具栏中双击对应生命周期阶段执行,也可在命令行使用 mvn [阶段名称]
命令执行,如 mvn clean
、mvn compile
、mvn package
等。
七、单元测试
(一)JUnit 单元测试基础
JUnit 是流行的 Java 测试框架,用于对最小功能单元(方法)进行测试。与传统的在 main
方法中测试相比,JUnit 具有测试代码与源代码分离、可自动化测试、能自动生成测试报告等优点。
例如,对 UserService
中的 getAge
方法进行单元测试,首先在 pom.xml
中引入 JUnit 依赖:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.1</version>
</dependency>
然后在 test/java
目录下创建测试类 UserServiceTest
,编写测试方法并使用 @Test
注解:
import org.junit.jupiter.api.Test;
public class UserServiceTest {
@Test
public void testGetAge() {
Integer age = new UserService().getAge("110002200505091218");
System.out.println(age);
}
}
JUnit 单元测试类名命名规范为 XxxxxTest
,测试方法必须声明为 public void
。
(二)断言
JUnit 提供了断言方法来判断被测试方法是否符合预期。例如:
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class UserServiceTest {
@Test
public void testGetAge() {
Integer expectedAge = 20;
Integer actualAge = new UserService().getAge("110002200505091218");
Assertions.assertEquals(expectedAge, actualAge, "年龄计算错误");
}
}
上述代码使用 assertEquals
断言方法检查实际年龄与预期年龄是否相等,若不相等则输出错误提示信息。
(三)常见注解
@Test
:修饰测试方法,使其能被执行。@ParameterizedTest
:用于参数化测试,可让单个测试方法多次运行,每次参数不同,使用时不再需要@Test
注解。@ValueSource
:为参数化测试提供参数来源,需与@ParameterizedTest
配合使用。@DisplayName
:指定测试类或方法显示的名称。@BeforeEach
:修饰实例方法,在每个测试方法执行前执行,用于初始化资源。@AfterEach
:修饰实例方法,在每个测试方法执行后执行,用于释放资源。@BeforeAll
:修饰静态方法,在所有测试方法前仅执行一次,用于初始化资源。@AfterAll
:修饰静态方法,在所有测试方法后仅执行一次,用于释放资源。
例如:
import org.junit.jupiter.api.*;
import java.util.ArrayList;
import java.util.List;
@DisplayName("用户服务测试类")
public class UserServiceTest {
private UserService userService;
@BeforeEach
void setUp() {
userService = new UserService();
}
@AfterEach
void tearDown() {
userService = null;
}
@BeforeAll
static void initAll() {
System.out.println("所有测试方法开始前执行一次");
}
@AfterAll
static void cleanAll() {
System.out.println("所有测试方法结束后执行一次");
}
@Test
@DisplayName("测试获取年龄方法")
void testGetAge() {
Integer age = userService.getAge("110002200505091218");
System.out.println(age);
}
@ParameterizedTest
@ValueSource(strings = {"110002200505091218", "110002200305091218"})
@DisplayName("参数化测试获取年龄方法")
void testParamGetAge(String id) {
Integer age = userService.getAge(id);
System.out.println(age);
}
}
(四)依赖范围与单元测试
在单元测试中,通常将测试框架依赖(如 JUnit)的范围设置为 test
,确保其仅在测试阶段使用,不会被打包到最终的项目发布包中。
八、Maven 常见问题及解决
在使用 Maven 过程中,可能会遇到依赖下载不完整的问题,表现为在 maven 仓库中生成 xxx.lastUpdated
文件。解决方法如下:
- 根据依赖坐标,在仓库中找到对应的
xxx.lastUpdated
文件并删除,然后重新加载项目。 - 使用命令
del /s *.lastUpdated
批量递归删除指定目录下的xxx.lastUpdated
文件,再重新加载项目。若重新加载后 Maven 面板仍报红,可关闭 IDEA 并重新打开项目。
九、总结
通过对 Maven 的学习,我们掌握了其在项目管理、构建、依赖管理和测试等方面的强大功能。合理运用 Maven 能够提高项目的开发效率、维护性和可扩展性,为 Java 项目开发提供有力支持。在实际项目中,还需不断实践和探索,深入理解 Maven 的各种特性和应用场景,以更好地发挥其作用。
以上就是关于 Maven 基础学习的总结内容,希望对读者有所帮助。在学习过程中,建议读者结合实际项目进行操作,加深对 Maven 的理解和掌握。