MAVEN利器:一文带你了解MAVEN中的依赖管理

news2024/9/25 11:14:57

前言:

强大的构建工具——Maven。作为Java生态系统中的重要组成部分,Maven为开发人员提供了一种简单而高效的方式来构建、管理和发布Java项目。无论是小型项目还是大型企业级应用,Maven都能帮助开发人员轻松处理依赖管理、编译、测试和部署等任务。

在上一篇文章中,我们学习了如何在IDEA中配置MAVEN环境以及如何创建MAVEN工程。从最开始我们就介绍过MAVEN的强大就在于他有中央仓库和私有仓库,通过这两个仓库我们可以快速的使用我们想用的依赖项,加快项目进展。而这节课我们就要学习MAVEN的依赖管理,学习如何使用这些依赖项来进行项目的构建。

我们这篇文章从四点出发来介绍依赖管理,分别是:依赖配置依赖传递依赖范围生命周期 

目录

前言:

1.依赖配置:

2.依赖传递:

3.依赖范围:

4.生命周期:

总结:


1.依赖配置:

当前项目运行的时候所需要的jar包,一个项目中可以引入多个依赖

在pom.xml文件中,你可以使用<dependencies>元素来定义项目的依赖项。每个依赖项都由一个<dependency>元素表示,通常包括以下几个关键信息:

  1. groupId: 定义依赖项的组织或者项目组的唯一标识符。
  2. artifactId: 定义依赖项的模块或项目的唯一标识符。
  3. version: 定义依赖项的版本号。
  4. scope: 定义依赖项的作用范围,比如compile(编译时必须依赖)、test(只在测试时依赖)、runtime(在运行时依赖)等。
  5. optional: 定义依赖项是否是可选的。

以下是一个示例的pom.xml文件,展示了如何使用Maven进行依赖配置:

<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>org.example</groupId>
  <artifactId>untitled6</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>untitled6</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>


  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.2</version>
    </dependency>

  </dependencies>
  
  
</project>

如图我们自己添加了一个名字叫做commons-logging的依赖项 

我们可以在maven面板中观察是否添加成功,如果添加成功,我们可以看到

 在Maven中,当你构建或运行项目时,它会自动下载并管理这些依赖项,确保项目可以正确地编译和运行。此外,Maven还支持传递性依赖,即如果一个依赖项依赖另一个依赖项,Maven会自动处理这种情况,以保证所有依赖项都能正确加载。

需要注意的是,很多同学可能第一次添加依赖项的时候,并不会有提示字符,这是因为我们并没有使用过这项依赖,因此不会有,只要我们使用过这个依赖之后,以后我们再使用的话,就会有提示了,在这里我给出一个maven仓库的网站,通过这个网站我们可以降低使用新的依赖项的难度:
Maven Repository: Search/Browse/Explore (mvnrepository.com)

这个网站里面提供了详细的坐标,我们直接复制就可以使用了。

2.依赖传递:

当一个项目依赖于其他库或模块时,Maven会自动解析和管理这些依赖的过程。

Maven使用依赖传递来处理项目依赖关系。当你在项目的pom.xml文件中定义一个依赖项时,Maven会自动解析该依赖项所依赖的其他依赖项,并将它们添加到构建路径中。

依赖传递有以下几个重要的概念:

1. 直接依赖(Direct Dependencies):这些是直接在pom.xml文件中定义的依赖项,它们是项目直接依赖的库或模块。

2. 传递性依赖(Transitive Dependencies):这些是由直接依赖项引入的间接依赖项。当一个直接依赖项依赖于其他库或模块时,这些依赖项也会被自动引入到项目中作为传递性依赖项。

3. 冲突解决(Dependency Conflict Resolution):当不同的直接或间接依赖项引入了相同的库或模块但版本不同时,就会发生依赖冲突。Maven会自动尝试解决冲突,通常选择最近版本的库或模块来满足所有的依赖关系。

通过这种依赖传递的机制,Maven可以简化项目的构建和管理。开发者只需要定义直接依赖项,而不需要关心这些依赖项所依赖的其他库和模块。

当构建或运行项目时,Maven会自动下载和管理所有的直接和传递性依赖项。它会根据依赖关系图来确保正确的顺序加载和运行这些依赖项,从而减少开发人员的工作量,并提高项目构建的可靠性和稳定性。

总结起来,Maven的依赖传递机制通过自动解析和管理直接和传递性依赖项,简化了项目的构建和管理过程。它可以根据依赖关系图自动加载所需的库和模块,并解决冲突以确保项目的正常构建和运行。

总结起来一句话就是:有的依赖项可能本身还会依赖其他的依赖项,而在实际使用的时候,我们不用考虑这些依赖项的版本协调问题,我们只需要安装好最大的依赖项,那么maven就会自动帮我们配置好所有的依赖项以及版本问题。

如图所示,我们当前使用的这个依赖也调用了其他的两个依赖项,但是我们不用在写出来小的依赖项:

需要注意的是:依赖不可以形成循环,会导致报错。

循环依赖可能导致以下问题:

  1. 编译错误:循环依赖会使编译器陷入无限循环,无法解析模块的依赖关系,从而导致编译错误。

  2. 运行时错误:循环依赖可能导致模块在运行时产生意想不到的行为,例如死锁、无限递归等问题。

  3. 可测试性下降:循环依赖会增加模块之间的耦合度,降低单元测试和集成测试的可行性和可靠性。

  4. 维护困难:循环依赖会增加代码的复杂性,降低代码的可读性和可维护性,使项目变得难以维护和扩展。

为了解决循环依赖问题,开发者可以考虑以下几种方法:

  1. 重构代码:重新设计模块之间的依赖关系,尽量避免形成循环依赖。

  2. 提取接口或抽象层:通过引入接口或抽象层,使模块之间依赖于抽象而不是具体的实现,以减少循环依赖的可能性。

  3. 模块解耦:将循环依赖的模块拆分成更小的模块,减少模块之间的直接依赖关系。

  4. 依赖倒置原则:遵循依赖倒置原则,使高层模块依赖于抽象而不是具体的实现,通过依赖注入等方式解决循环依赖问题。

3.依赖范围:

在Maven中,依赖范围(Dependency Scope)用于定义依赖项在不同的阶段和环境中的使用情况。通过scope指定适当的依赖范围,可以控制项目构建时依赖的传递性和运行时的类路径。

Maven提供了以下几种常见的依赖范围:

  1. compile(默认范围):这是最常用的依赖范围,表示该依赖项在编译、测试和运行时均可用。它会被传递给依赖项的所有模块。

  2. provided:表示该依赖项在编译和测试时可用,但在运行时由容器或环境提供。例如,Servlet API在Java EE容器中提供,因此在构建项目时需要它,但在运行时不需要该依赖项。

  3. runtime:表示该依赖项在运行时可用,但在编译和测试时不需要。通常用于一些类库,比如数据库驱动程序,只在运行时需要。

  4. test:表示该依赖项仅在测试环境中可用,不会传递给依赖项的模块。它用于编写和运行测试用例,不会影响项目的部署和运行。

  5. system:表示该依赖项需要显式地提供,并且不从Maven仓库中获取。需要通过<systemPath>元素指定依赖项的路径。

  6. import:该范围仅在 <dependencyManagement> 区域中使用,允许您在不引入实际依赖项的情况下控制属性传递。

下面是一个示例,展示了如何在pom.xml文件中使用依赖范围:

<dependencies>
  <dependency>
    <groupId>com.example</groupId>
    <artifactId>my-library</artifactId>
    <version>1.0.0</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
    <version>2.4.0</version>
    <scope>runtime</scope>
  </dependency>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
  </dependency>
</dependencies>

在这个示例中,my-library是一个编译和运行时都需要的依赖项,servlet-api是一个提供的依赖项,hsqldb是一个在运行时需要的依赖项,junit是一个仅在测试时使用的依赖项。

通过设置适当的依赖范围,可以优化项目的构建和运行策略,减少运行时依赖项的大小,并提高构建和部署的效率。

4.生命周期:

Maven的生命周期(Lifecycle)定义了一组相互关联的构建阶段,用于管理项目的构建过程。Maven生命周期由多个阶段(Phase)组成,每个阶段又包含了多个插件目标(Goal)。

Maven定义了三个标准的生命周期:

  1. clean生命周期负责清理项目构建产生的文件。包含了pre-cleancleanpost-clean三个阶段。

    • pre-clean:在执行实际的清理操作之前进行一些准备和配置。
    • clean:清理构建产生的文件,即删除target目录及其内容。
    • post-clean:在清理操作完成后执行一些额外的操作。
  2. default生命周期:主要负责构建项目。包含了项目的主要阶段,如编译、测试、打包、部署等。默认情况下,执行mvn install命令会触发default生命周期。

    • validate:验证项目的正确性。
    • compile:编译项目的源代码。
    • test:运行单元测试。
    • package:将编译后的代码打包。
    • verify:对集成测试进行验证。
    • install:将构建的包安装到本地仓库,供本地其他项目使用。
    • deploy:将构建的包复制到远程仓库,供其他项目或团队使用。
  3. site生命周期生成项目的文档和站点。包含了与项目报告和站点相关的阶段。

    • pre-site:在生成站点之前执行一些准备工作。
    • site:生成项目的站点文档。
    • post-site:在生成站点之后执行一些额外的操作。
    • site-deploy:将站点部署到服务器上,以供访问。

除了标准的生命周期,Maven还支持自定义生命周期,以满足特定项目的需求。自定义生命周期可以根据项目的构建流程和需求进行定义,并在pom.xml文件中进行配置。

在构建过程中,Maven会按照生命周期、阶段和插件目标的顺序依次执行。每个阶段可能会触发一个或多个插件目标的执行。插件目标通常是由Maven插件提供的功能,用于执行构建过程中的具体任务。

使用Maven生命周期可以将项目的构建过程标准化和自动化。通过定义合适的插件目标和配置构建配置文件,开发团队可以快速构建、测试和部署项目,并生成项目文档和报告。

我们可以看一看maven面板中的生命周期:

  1. clean:在构建之前进行项目清理的阶段。它执行预定义的插件目标以删除上一次构建生成的目标文件和目录。

  2. validate:验证项目的正确性并进行初步的静态分析。它可以用于检查项目的基本结构是否正确,并查找潜在的问题。

  3. compile:编译项目的源代码。在此阶段,Maven使用编译插件将源代码编译为目标字节码文件。

  4. test:运行项目的单元测试。在此阶段,Maven会执行测试插件来运行已编写的单元测试,并生成测试报告。

  5. package:将编译后的代码打包成可发布的格式。在此阶段,Maven会将编译好的类文件、资源文件等打包到指定的格式中,例如JAR、WAR或者其他自定义的格式。

  6. verify:对集成测试进行验证。在此阶段,Maven会执行集成测试插件来运行更广泛的测试,以确保代码在集成环境中能够正常工作。

  7. install:将构建的包安装到本地仓库。在此阶段,Maven会将项目的构建结果安装到本地仓库,以供其他本地项目使用或构建间接依赖它的项目使用。

  8. site:生成项目的站点文档。在此阶段,Maven会执行站点插件来生成项目的文档、报告和其他站点相关内容,以供团队成员查阅。

  9. deploy:将构建的包复制到远程仓库。在此阶段,Maven会将构建的包复制到远程仓库,供其他团队成员或者其他项目使用。

这些阶段按照顺序执行,每个阶段会执行相应的插件目标以实现具体功能。通过定义和配置插件目标,开发者可以根据项目需求来扩展或自定义每个阶段的行为,以满足特定的需求。Maven生命周期的清晰定义和执行顺序有助于规范和自动化项目的构建、测试和部署过程。

 生命周期是可以执行的,我们可以直接在maven控制面板中进行我们指定的操作来满足我们项目的需求。

总结:

在软件开发中,使用Maven进行依赖管理是非常重要和高效的。Maven提供了一种简单而强大的方式来管理项目的依赖项,使开发人员能够更好地控制项目构建和部署过程。

通过Maven的依赖管理机制,我们可以轻松地定义和管理项目的依赖关系。只需在项目的pom.xml文件中指定依赖的坐标和版本号,Maven就能够自动下载依赖项,并将其包含在项目的构建路径中。这极大地简化了项目的设置和配置过程,使开发人员能够更专注于业务逻辑的开发。

此外,Maven的依赖管理还支持依赖范围的定义,使得我们可以根据不同的环境和需求来控制依赖项的传递性。通过合理设置依赖的范围,可以减小构建的大小,提高项目的性能和可维护性。

另外,Maven还通过集中式的仓库管理依赖项,使得依赖的获取和更新变得十分便捷。我们可以轻松地从Maven中央仓库或者私有仓库中获取所需的依赖项,并自动解决依赖冲突问题。

总之,通过Maven的依赖管理机制,我们能够更加高效地管理项目的依赖项,并减少因为依赖问题而导致的开发和部署的困扰。它帮助我们构建了一个稳定、可靠和可维护的开发环境,提升了开发效率和代码质量。因此,掌握Maven的依赖管理是每个开发人员都应该具备的重要技能。

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/958007.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iOS 使用coreData存贮页面的模型数据中的字典

我们使用coreData时候&#xff0c;会遇到较为复杂的数据类型的存贮&#xff0c;例如&#xff0c;我们要存一个模型&#xff0c;但是一个模型里面有个字典&#xff0c;这时候&#xff0c;我们该如何存贮呢 如图所示&#xff0c;一个对象中含有一个字典 我们实现一个公共的方法…

无涯教程-Flutter - 安装步骤

本章将指导您详细在本地计算机上安装Flutter。 在Windows中安装 在本节中&#xff0c;让无涯教程看看如何在Windows系统中安装 Flutter SDK 及其要求。 第1步 - 转到URL,https: //flutter.dev/docs/get-started/install/windows并下载最新的Flutter SDK。 第2步 - 将zip归档…

(leetcode1761一个图中连通三元组的最小度数,暴力+剪枝)-------------------Java实现

&#xff08;leetcode1761一个图中连通三元组的最小度数&#xff0c;暴力剪枝&#xff09;-------------------Java实现 题目表述 给你一个无向图&#xff0c;整数 n 表示图中节点的数目&#xff0c;edges 数组表示图中的边&#xff0c;其中 edges[i] [ui, vi] &#xff0c;…

电脑锁屏怎么设置?这5个方法都管用!

“我的电脑好像没有锁屏&#xff0c;就算我很久没用电脑也不会息屏。这是为什么呢&#xff1f;有什么方法可以为电脑设置锁屏吗&#xff1f;” 电脑锁屏是保护隐私和安全的重要手段。如果我们希望在不使用电脑时电脑自动进行锁屏&#xff0c;是可以手动设置的。那么&#xff0c…

EXPLAIN的用法

一、语法 EXPLAIN SQL语句二、各字段解释 1、table ● 单表&#xff1a;显示这一行的数据是关于哪张表的。 ● 多表关联&#xff1a;t1为驱动表&#xff0c;t2为被驱动表。 注意&#xff1a; 内连接时&#xff0c;MySQL性能优化器会自动判断哪个表是驱动表&#xff0c;哪个表…

什么是HTTPS协议?与HTTP协议区别?

一、协议科普 HTTP协议&#xff08;超文本传输协议&#xff09;是一种用于在计算机网络上传输超文本的应用层协议。它是一种客户端-服务器协议&#xff0c;允许客户端通过Web浏览器等方式向服务器发送请求&#xff0c;服务器则返回响应。HTTP协议是构建万维网&#xff08;WWW&…

使用pip命令安装库,装到其他环境中的问题。

问题描述&#xff1a;我们在pycharm中创建了新的虚拟环境&#xff0c;但是在其终端使用Pip命令安装库时&#xff0c;发现库却安装到了其他conda创建的环境中。图示安装gym库&#xff0c;刚开始安装到了其他地方&#xff0c;第二次正确安装。 原因分析&#xff1a;安装库时&…

USB fastboot

1 Samsung fastboot flashing unlock 2 bootloader增加解锁密码 diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c index e4d46e4..1b4b450 100755 --- a/app/aboot/aboot.c b/app/aboot/aboot.c -2613,6 2613,20 void cmd_oem_unlock(const char *arg, void *data,…

[ES]mac安装es、kibana、ik分词器

一、安装es和kibana 1、创建一个网络&#xff0c;网络内的框架(eskibana)互联 docker network create es-net 2、下载es和kibana docker pull elasticsearch:7.12.1 docker pull kibana:7.12.1 3、运行docker命令部署单点eskibana&#xff08;用来操作es&#xff09; doc…

分布式搜索引擎

1 DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1.1.DSL查询分类 Elasticsearch提供了基于JSON的DSL&#xff08;Domain Specific Language&#xff09;来定义查询。常见的查询类型包括&#xff1a; 查询所有&#xff1a;查询出所有数据&#xff0c;一…

开启智能时代:深度解析智能文档分析技术的前沿与应用

开启智能时代&#xff1a;深度解析智能文档分析技术的前沿与应用 本章主要介绍文档分析技术的理论知识&#xff0c;包括背景介绍、算法分类和对应思路。通过本文学习&#xff0c;你可以掌握&#xff1a;1. 版面分析的分类和典型思想 2. 表格识别的分类和典型思想 3. 信息提取的…

C语言函数编程指南:实现模块化和可维护的代码

函数 1. 前言2. 函数是什么3. C语言中函数的分类3.1 库函数3.2 自定义函数 4. 函数的参数4.1 实际参数&#xff08;实参&#xff09;4.2 形式参数&#xff08;形参&#xff09; 5. 函数的调用5.1 传值调用5.2 传址调用 6. 阶段练习6.1 打印100~200之间的素数6.2 打印1000到2000…

WEBGL(2):绘制单个点

代码如下&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevi…

基于微信小程序的社交用户交流系统

本文从管理员、用户的功能要求出发&#xff0c;微信小程序的社交系统中的功能模块主要是实现首页、个人中心、用户管理、用户技能管理、技能分类管理、交流论坛、系统管理。经过认真细致的研究&#xff0c;精心准备和规划&#xff0c;最后测试成功&#xff0c;系统可以正常使用…

RFID技术:工业稳定的关键

RFID 技术在工业领域的应用让生产和运营更加稳定高效。这种无线通信技术可以通过无线电波实现信息的读取和写入&#xff0c;使得数据采集、存储和传输变得更加便捷。在工业生产中&#xff0c;RFID 的应用可以帮助企业提高生产效率、降低成本、提高产品质量&#xff0c;从而让工…

Mike11;Mike21深度技能解析

数学模型在水环境评价、防洪评价和排污口论证等领域中有重要作用&#xff0c;随着人类活动的不断增加和环境问题的日益突出&#xff0c;对水资源和水环境的保护与管理变得至关重要。为了更好地理解和应对这些挑战&#xff0c;数学模型成为一种强大的工具&#xff0c;能够提供量…

<Cadence> PCB封装制作(一) 封装组成元素介绍制作表贴焊盘

目录 01 封装的组成元素 02 焊盘Design Layers组成 03 制作表贴焊盘 获取表贴器件&#xff08;0603电阻&#xff09;的相关信息 制作表贴器件&#xff08;0603电阻&#xff09;焊盘封装 04 文章总结 大家好&#xff0c;这里是程序员杰克。一名平平无奇的嵌入式软件工程师…

【100天精通python】Day49:python web编程_web框架,Flask的使用

目录 1 Web 框架 2 python 中常用的web框架 3 Flask 框架的使用 3.1 Flask框架安装 3.2 第一个Flask程序 3.3 路由 3.3.1 基本路由 3.3.2 动态路由 3.3.3 HTTP 方法 3.3.4 多个路由绑定到一个视图函数 3.3.5 访问URL 参数的路由 3.3.6 带默认值的动态路由 3.3.7 带…

Cell | 超深度宏基因组!复原消失的肠道微生物

期刊&#xff1a;Cell IF&#xff1a;64.5 (Q1) 发表时间&#xff1a;2023.6 研究背景 不同的生活方式会影响微生物组组成&#xff0c;但目前微生物组的研究严重偏向于西方工业化人群&#xff0c;其中工业化人群的特点是微生物群多样性较低。为了理解工…

Kubernetes技术--k8s核心技术 configMap

1.概述 configMap最主要的作用是存储一些不加密的数据到/etcd,让pod以变量或者数据卷(volume)挂载到容器。 应用场景:配置文件、存储信息等 2.使用 -1.创建配置文件。 这里我们需要先编写一个配置文件。使用redis,如下所示: