【学习总结|DAY024】Maven基础

embedded/2025/1/1 10:28:50/

一、引言

在 Java 项目开发中,Maven 是一款至关重要的工具,它能够极大地提升项目管理与构建的效率。本文将详细介绍 Maven 的核心概念、安装配置、在 IDEA 中的集成应用、依赖管理、项目构建生命周期、单元测试以及常见问题的解决方法,并结合实际代码示例进行说明。

二、Maven 概述

(一)定义与作用

Maven 是 apache 旗下的开源项目管理和构建工具,基于项目对象模型(POM),可实现标准化、跨平台(Linux、Windows、MacOS)的自动化项目构建,提供统一项目结构,并方便管理项目依赖的资源(jar 包)。

(二)仓库类型

  1. 本地仓库:位于本地计算机的特定目录,用于存储已下载的 jar 包,如 D:\develop\apache-maven-3.9.4\mvn_repo
  2. 中央仓库:由 Maven 团队维护的全球唯一仓库,地址为 https://repo1.maven.org/maven2/
  3. 远程仓库(私服):通常由公司团队搭建,用于存储内部或特定的 jar 包资源。

查找依赖(jar)时,先在本地仓库查找,若不存在则依次从远程仓库、中央仓库获取。

三、Maven 安装

  1. 解压 apache-maven-3.9.4-bin.zip 文件。
  2. 配置本地仓库:在 conf/settings.xml 中修改 <localRepository> 标签为指定目录,如 <localRepository>D:\develop\apache-maven-3.9.4\mvn_repo</localRepository>
  3. 配置阿里云私服:在 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>
  1. 配置环境变量:设置 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.xmlLocal 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> 标签需指定 groupIdartifactId 和 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(默认)YYYlog4j
test-Y-junit
providedYY-servlet-api
runtime-YYjdbc 驱动

例如,将 junit-jupiter 依赖设置为仅在测试程序范围有效:

<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.9.3</version><scope>test</scope>
</dependency>

六、项目构建生命周期

Maven 有 3 套相互独立的生命周期:cleandefault 和 site

  • clean:主要用于清理上一次构建生成的文件,包含 pre-cleancleanpost-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:将编译后的文件打包成可分发的格式,如 jarwar 等。
    • verify:对打包后的文件进行验证,确保其符合质量标准。
    • install:将项目安装到本地仓库,以便其他项目可以引用。
    • deploy:将项目部署到远程仓库,供其他开发人员或项目使用。
  • site:用于生成项目报告、发布站点等,包含 pre-sitesitepost-sitesite-deploy 等阶段。

在同一套生命周期中,运行后面的阶段时,前面的阶段会自动依次执行。可在 IDEA 的 Maven 工具栏中双击对应生命周期阶段执行,也可在命令行使用 mvn [阶段名称] 命令执行,如 mvn cleanmvn compilemvn 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 注解:

java">import org.junit.jupiter.api.Test;public class UserServiceTest {@Testpublic void testGetAge() {Integer age = new UserService().getAge("110002200505091218");System.out.println(age);}
}

JUnit 单元测试类名命名规范为 XxxxxTest,测试方法必须声明为 public void

(二)断言

JUnit 提供了断言方法来判断被测试方法是否符合预期。例如:

java">import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;public class UserServiceTest {@Testpublic 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:修饰静态方法,在所有测试方法后仅执行一次,用于释放资源。

例如:

java">import org.junit.jupiter.api.*;import java.util.ArrayList;
import java.util.List;@DisplayName("用户服务测试类")
public class UserServiceTest {private UserService userService;@BeforeEachvoid setUp() {userService = new UserService();}@AfterEachvoid tearDown() {userService = null;}@BeforeAllstatic void initAll() {System.out.println("所有测试方法开始前执行一次");}@AfterAllstatic 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 文件。解决方法如下:

  1. 根据依赖坐标,在仓库中找到对应的 xxx.lastUpdated 文件并删除,然后重新加载项目。
  2. 使用命令 del /s *.lastUpdated 批量递归删除指定目录下的 xxx.lastUpdated 文件,再重新加载项目。若重新加载后 Maven 面板仍报红,可关闭 IDEA 并重新打开项目。

九、总结

通过对 Maven 的学习,我们掌握了其在项目管理、构建、依赖管理和测试等方面的强大功能。合理运用 Maven 能够提高项目的开发效率、维护性和可扩展性,为 Java 项目开发提供有力支持。在实际项目中,还需不断实践和探索,深入理解 Maven 的各种特性和应用场景,以更好地发挥其作用。

以上就是关于 Maven 基础学习的总结内容,希望对读者有所帮助。在学习过程中,建议读者结合实际项目进行操作,加深对 Maven 的理解和掌握。


http://www.ppmy.cn/embedded/149768.html

相关文章

一个简单的机器学习实战例程,使用Scikit-Learn库来完成一个常见的分类任务——**鸢尾花数据集(Iris Dataset)**的分类

机器学习实战通常是将理论与实践结合&#xff0c;通过实际的项目或案例&#xff0c;帮助你理解并应用各种机器学习算法。下面是一个简单的机器学习实战例程&#xff0c;使用Scikit-Learn库来完成一个常见的分类任务——**鸢尾花数据集&#xff08;Iris Dataset&#xff09;**的…

指定Bean加载顺序的能力

springboot遵从约定大于配置的原则&#xff0c;极大程度的解决了配置繁琐的问题。在此基础上&#xff0c;又提供了spi机制&#xff0c;用spring.factories可以完成一个小组件的自动装配功能。 在一般业务场景&#xff0c;可能是不需要关心一个bean是如何被注册进spring容器的&…

在 macOS 和 Windows 平台上使用 SVN 的完整指南20241225

在 macOS 和 Windows 平台上使用 SVN 的完整指南 在现代开发环境中&#xff0c;版本控制工具是团队协作的基石&#xff0c;而 SVN&#xff08;Subversion&#xff09;作为一种经典的集中式版本控制系统&#xff0c;依然在许多企业中广泛应用。本文将从基础到进阶&#xff0c;带…

经典150-数组/字符串

文章目录 1.合并两个有序数组1.答案2.思路 2.移除元素1.答案2.思路 3.删除有序数组中的重复项1.答案2.思路 4.删除有序数组中的重复项 II1.答案2.思路 5.多数元素1.答案2.思路 6.轮转数组1.答案2.思路 7.买卖股票的最佳时机1.答案2.思路 8.买卖股票的最佳时机 II1.答案2.思路 9…

如何用一个统一的视角,分析RLHF下的各种算法?

写这篇文章的起因是&#xff0c;上周读了https://zhuanlan.zhihu.com/p/1082394115这篇知乎文章&#xff0c;文中探讨了关于DPO的局限性。在我之前写DPO的推导过程时&#xff08;https://zhuanlan.zhihu.com/p/721073733&#xff09;&#xff0c;我就一直有一个主观感觉&#x…

ARM 获取cpu个数

MPIDR_EL1寄存器 AFF0 &#xff1a;表示一个 core 中的第几个 thread&#xff0c;大多数 core 都是 single-threaded core&#xff0c;所以大多数 core 中的该值是 0. AFF1&#xff1a;表示一个 cluster 中的第几个 cpu AFF2/AFF3&#xff1a;表示系统中的第几个 cluster&#…

高级java每日一道面试题-2024年12月28日-并发篇-了解Semaphore吗?

如果有遗漏,评论区告诉我进行补充 面试官: 了解Semaphore吗? 我回答: 在Java高级面试中&#xff0c;Semaphore&#xff08;信号量&#xff09;是一个重要的并发控制工具&#xff0c;它用于控制同时访问特定资源的线程数量&#xff0c;以确保资源的合理使用。以下是对Semaph…

Springboot项目下面使用Vue3 + ElementPlus搭建侧边栏首页

Springboot项目下面、在html 页面 Vue3 ElementPlus 搭建侧边栏首页 1、效果图 2、static 文件下面的项目结构 3、代码实现 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>首页</title><…