【Maven】Maven 基础教程(二):Maven 的使用

Maven 基础教程》系列,包含以下 2 篇文章:

  • Maven 基础教程(一):基础介绍、开发环境配置
  • Maven 基础教程(二):Maven 的使用

😊 如果您觉得这篇文章有用 ✔️ 的话,请给博主一个一键三连 🚀🚀🚀 吧 (点赞 🧡、关注 💛、收藏 💚)!!!您的支持 💖💖💖 将激励 🔥 博主输出更多优质内容!!!

Maven 基础教程(二):Maven 的使用

  • 3.Maven 的使用
    • 3.1 核心概念:坐标
    • 3.2 pom.xml
    • 3.3 依赖
    • 3.4 依赖的传递
    • 3.5 依赖的排除
    • 3.6 继承
      • 3.6.1 概念
      • 3.6.2 作用
      • 3.6.3 一个例子
    • 3.7 聚合
      • 3.7.1 Maven 中的聚合
      • 3.7.2 继承和聚合的对应关系
      • 3.7.3 聚合的配置
      • 3.7.4 依赖循环问题

3.Maven 的使用

3.1 核心概念:坐标

数学中的坐标使用 x x x y y y z z z 三个 向量 作为空间的坐标系,可以在 空间 中唯一的定位到一个
在这里插入图片描述
Maven 中的坐标使用三个 向量Maven的仓库 中唯一的定位到一个 jar 包

  • groupId:公司或组织的 id,即公司或组织域名的 倒序,通常也会加上项目名称。例如:com.javatv.maven
  • artifactId:一个项目或者是项目中的一个模块的 id,即模块的名称,将来作为 Maven 工程的工程名。例如:auth
  • version:版本号。例如:1.0.0

坐标和仓库中 jar 包的存储路径之间的对应关系,如下:

<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>

上面坐标对应的 jar 包在 Maven 本地仓库中的位置:

Maven本地仓库根目录\javax\servlet\servlet-api\2.5\servlet-api-2.5.jar

3.2 pom.xml

  • POMProject Object Model项目对象模型。和 POM 类似的是 DOMDocument Object Model),文档对象模型。它们都是模型化思想的具体体现。
  • POM 表示将工程抽象为一个模型,再用程序中的对象来描述这个模型。这样我们就可以用程序来管理项目了。我们在开发过程中,最基本的做法就是将现实生活中的事物抽象为模型,然后封装模型相关的数据作为一个对象,这样就可以在程序中计算与现实事物相关的数据。
  • POM 理念集中体现在 Maven 工程根目录下 pom.xml 这个配置文件中。所以这个 pom.xml 配置文件就是 Maven 工程的 核心配置文件。其实学习 Maven 就是学这个文件怎么配置,各个配置有什么用。
<!-- 当前Maven工程的坐标 -->
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<!-- 当前Maven工程的打包方式,可选值有下面三种:-->
<!-- jar:表示这个工程是一个Java工程  -->
<!-- war:表示这个工程是一个Web工程 -->
<!-- pom:表示这个工程是“管理其他工程”的工程 -->
<packaging>jar</packaging><properties><!-- 工程构建过程中读取源码时使用的字符集 --><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties><!-- 当前工程所依赖的jar包 -->
<dependencies><!-- 使用dependency配置一个具体的依赖 --><dependency><!-- 在dependency标签内使用具体的坐标依赖我们需要的一个jar包 --><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><!-- scope标签配置依赖的范围 --><scope>test</scope></dependency>
</dependencies>

3.3 依赖

上面说到我们使用 Maven 最主要的就是使用它的依赖管理功能,引入依赖存在一个范围,Maven 的依赖范围包括:compileprovidedruntimetestsystem

  • compile:表示编译范围,指 A 在编译时依赖 B,该范围为默认依赖范围。编译范围的依赖会用在编译,测试,运行,由于运行时需要,所以编译范围的依赖会被打包。
  • providedprovied 依赖只有当 jdk 或者一个容器已提供该依赖之后才使用。provided 依赖在编译和测试时需要,在运行时不需要。例如:Servlet API 被 Tomcat 容器提供了。
  • runtimeruntime 依赖在运行和测试系统时需要,但在编译时不需要。例如:JDBC 的驱动包。由于运行时需要,所以 runtime 范围的依赖会被打包。
  • testtest 范围依赖在编译和运行时都不需要,只在测试编译和测试运行时需要。例如:Junit。由于运行时不需要,所以 test 范围依赖不会被打包。
  • systemsystem 范围依赖与 provided 类似,但是必须显示的提供一个对于本地系统中 jar 文件的路径。一般不推荐使用。
依赖范围编译测试运行时是否会被打入 jar
compile
provided
runtime
test
system

而在实际开发中,我们常用的就是 compiletestprovided

3.4 依赖的传递

A 依赖 B,B 依赖 C,那么在 A 没有配置对 C 的依赖的情况下,A 里面能不能直接使用 C?在以上的前提下,C 是否能够传递到 A,取决于 B 依赖 C 时使用的依赖范围。B 依赖 C 时使用 compile 范围:可以传递;B 依赖 C 时使用 testprovided 范围:不能传递。所以需要这样的 jar 包时,就必须在需要的地方明确配置依赖才可以。

3.5 依赖的排除

当 A 依赖 B,B 依赖 C,而且 C 可以传递到 A 的时候,A 不想要 C,需要在 A 里面把 C 排除掉。而往往这种情况都是为了避免 jar 包之间的冲突。
在这里插入图片描述
所以配置依赖的排除其实就是阻止某些 jar 包的传递。因为这样的 jar 包传递过来会和其他 jar 包冲突。

一般通过使用 excludes 标签配置依赖的排除:

<dependency><groupId>net.javatv.maven</groupId><artifactId>auth</artifactId><version>1.0.0</version><scope>compile</scope><!-- 使用excludes标签配置依赖的排除  --><exclusions><!-- 在exclude标签中配置一个具体的排除 --><exclusion><!-- 指定要排除的依赖的坐标(不需要写version) --><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions></dependency>

3.6 继承

3.6.1 概念

Maven 工程之间,A 工程继承 B 工程

  • B 工程:父工程
  • A 工程:子工程

本质上是 A 工程的 pom.xml 中的配置继承了 B 工程中 pom.xml 的配置。

3.6.2 作用

在父工程中统一管理项目中的依赖信息,具体来说是管理依赖信息的版本。

它的背景是:

  • 对一个比较大型的项目进行了模块拆分。
  • 一个 project 下面,创建了很多个 module
  • 每一个 module 都需要配置自己的依赖信息。

它背后的需求是:

  • 在每一个 module 中各自维护各自的依赖信息很容易发生出入,不易统一管理。
  • 使用同一个框架内的不同 jar 包,它们应该是同一个版本,所以整个项目中使用的框架版本需要统一。
  • 使用框架时所需要的 jar 包组合(或者说依赖信息组合)需要经过长期摸索和反复调试,最终确定一个可用组合。这个耗费很大精力总结出来的方案不应该在新的项目中重新摸索。
  • 通过在父工程中为整个项目维护依赖信息的组合既保证了整个项目使用规范、准确的 jar 包;又能够将以往的经验沉淀下来,节约时间和精力。

3.6.3 一个例子

1️⃣ 一般在模块化开发中一般都会创建一个父工程,如下:

在这里插入图片描述
在这里插入图片描述
父工程创建好之后,要修改它的打包方式:

<!-- 当前工程作为父工程,它要去管理子工程,所以打包方式必须是 pom -->
<packaging>pom</packaging>

只有打包方式为 pom 的 Maven 工程能够管理其他 Maven 工程。打包方式为 pom 的 Maven 工程中不写业务代码,它是专门管理其他 Maven 工程的工程,所以可以将生成的 src 目录删除。

2️⃣ 创建模块工程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后可以在父工程的 pom 文件中看到:

在这里插入图片描述
而子工程的 pom 如下:

在这里插入图片描述
3️⃣ 在父工程中配置依赖的统一管理

使用 dependencyManagement 标签配置对依赖的管理,如下:

<?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>net.javatv.maven</groupId><artifactId>maven-demo-parent</artifactId><packaging>pom</packaging><version>1.0-SNAPSHOT</version><modules><module>demo-module</module></modules><dependencyManagement><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>5.3.19</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>5.3.19</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.19</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.3.19</version></dependency></dependencies></dependencyManagement></project>

而实际上被管理的依赖并没有真正被引入到工程。

4️⃣ 子工程中引用那些被父工程管理的依赖

关键点:省略版本号

子工程引用父工程中的依赖信息时,可以把版本号去掉。把版本号去掉就表示子工程中这个依赖的版本由父工程决定,具体来说是由父工程的 dependencyManagement 来决定。

子工程 pom 如下:

<?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"><!-- 使用parent标签指定当前工程的父工程 --><parent><artifactId>maven-demo-parent</artifactId><groupId>net.javatv.maven</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><!-- 子工程的坐标 --><!-- 如果子工程坐标中的groupId和version与父工程一致,那么可以省略 --><artifactId>demo-module</artifactId><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId></dependency></dependencies></project>

此时,被管理的依赖才被引入到工程。
在这里插入图片描述
5️⃣ 修改父工程依赖信息的版本

这个修改可以是降级,也可以是升级,但一般来说都是升级。

在这里插入图片描述
6️⃣ 父工程中声明自定义属性

对同一个框架的一组 jar 包最好使用相同的版本,为了方便升级框架,可以将 jar 包的版本信息统一提取出来,统一声明版本号:

<!-- 通过自定义属性,统一指定Spring的版本 -->
<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><!-- 自定义标签,维护Spring版本数据 --><spring.version>5.3.19</spring.version>
</properties>

在需要的地方使用 ${} 的形式来引用自定义的属性名,真正实现一处修改,处处生效。

<?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>net.javatv.maven</groupId><artifactId>maven-demo-parent</artifactId><packaging>pom</packaging><version>1.0-SNAPSHOT</version><modules><module>demo-module</module></modules><!-- 通过自定义属性,统一指定Spring的版本 --><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><!-- 自定义标签,维护Spring版本数据 --><spring.version>5.3.19</spring.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring.version}</version></dependency></dependencies></dependencyManagement></project>

编写一套符合要求、开发各种功能都能正常工作的依赖组合并不容易。如果公司里已经有人总结了成熟的组合方案,那么再开发新项目时,如果不使用原有的积累,而是重新摸索,会浪费大量的时间。为了提高效率,我们可以使用工程继承的机制,让成熟的依赖组合方案能够保留下来。如下:
在这里插入图片描述
如上图所示,公司级的父工程中管理的就是成熟的依赖组合方案,各个新项目、子系统各取所需即可。

3.7 聚合

聚合,指分散的聚集到一起,即部分组成整体。

3.7.1 Maven 中的聚合

使用一个总工程将各个模块工程汇集起来,作为一个整体对应完整的项目,实际就是 module 标签。

  • 项目:整体
  • 模块:部分

3.7.2 继承和聚合的对应关系

继承 关系角度来看:

  • 父工程
  • 子工程

聚合 关系角度来看:

  • 总工程
  • 模块工程

3.7.3 聚合的配置

在总工程中配置 modules 即可:

<modules><module>demo-module</module>
</modules>

3.7.4 依赖循环问题

如果 A 工程依赖 B 工程,B 工程依赖 C 工程,C 工程又反过来依赖 A 工程,那么在执行构建操作时会报下面的错误:

DANGER[ERROR] [ERROR] The projects in the reactor contain a cyclic reference:

这个错误的含义是:循环引用。

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

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

相关文章

Qt中关于信号与槽函数的思考

信号与槽函数的思考 以pushbutton控件为例&#xff0c;在主界面上放置一个pushbutton控件&#xff0c;点击右键选择关联槽函数&#xff0c;关联一个click函数&#xff0c;如下图所示&#xff1a; 在该函数中&#xff0c;实现了一个点击pushbutton按钮后&#xff0c;弹出一个窗…

go并发模式之----使用时顺序模式

常见模式之二&#xff1a;使用时顺序模式 定义 顾名思义&#xff0c;起初goroutine不管是怎么个先后顺序&#xff0c;等到要使用的时候&#xff0c;需要按照一定的顺序来&#xff0c;也被称为未来使用模式 使用场景 每个goroutine函数都比较独立&#xff0c;不可通过参数循环…

DOM 获取父子节点

DOM 是以树状结构排列的&#xff0c;所以父子关系是相对的&#xff0c;当li为我们的目标节点的时候&#xff0c;ul为其父节点&#xff0c;其他li为它的兄弟节点&#xff0c;li里面包含的标签为子节点&#xff0c;以此类推。 那我们如何找父节点&#xff1f; 元素.parentNode&am…

【计算机网络——应用层】http协议

文章目录 1. http协议1.1 http协议简介1.2 url组成1.3 urlencode与urldecode 2. http协议的格式2.1 http协议的格式2.2 一些细节问题 3. http的方法、状态码和常见响应报头3.1 http请求方法3.2 http状态码3.3 http常见的响应报头属性 4. 一个非常简单的http协议服务端5. http长…

【X806开发板试用】文章一 ubuntu开发环境搭建

一、环境配置 官方链接&#xff1a; 环境配置 1.安装必要的库和软件 sudo apt-get install build-essential gcc g make zlib* libffi-dev e2fsprogs pkg-config flex bison perl bc openssl libssl-dev libelf-dev libc6-dev-amd64 binutils binutils-dev libdwarf-dev u-b…

pix2pix-zero

pix2pix-zero&#xff1a;零样本图像到图像转换 论文介绍 Zero-shot Image-to-Image Translation 关注微信公众号: DeepGoAI 项目地址&#xff1a;https://github.com/pix2pixzero/pix2pix-zero 论文地址&#xff1a;https://arxiv.org/abs/2302.03027 本文介绍了一种名为…

基于SpringBoot多模块项目引入其他模块时@Autowired无法注入

基于SpringBoot多模块项目引入其他模块时Autowired无法注入 一、问题描述1、解决方案 一、问题描述 启动Spring Boot项目时报 Could not autowire. No beans of ‘xxxxxxxx’ type found. 没有找到bean的实例&#xff0c;即spring没有实例化对象&#xff0c;也就无法根据配置文…

【LeetCode-中等】209.长度最小的子数组-双指针/滑动窗口

力扣题目链接 1. 暴力解法 这道题的暴力解法是两层嵌套for循环&#xff0c;第一层循环从 i 0 开始遍历至数组末尾&#xff0c;第二层循环从 j i 开始遍历至找到总和大于等于 target 的连续子数组&#xff0c;并将该连续子数组的长度与之前找到的子数组长度相比较&#xff0…

什么是IP公网?

IP公网是指互联网上可以公开访问的IP地址。它是经过互联网服务提供商&#xff08;ISP&#xff09;向用户提供的公共网络IP地址。与之相对的是内网IP地址&#xff0c;内网IP地址一般是由路由器或交换机分配给连接在局域网中的设备使用。 IP公网的作用非常广泛&#xff0c;可以应…

Web APIs知识点讲解(阶段二)

DOM-事件基础 一.事件 1.事件 目标&#xff1a;能够给 DOM元素添加事件监听 事件:事件是在编程时系统内发生的动作或者发生的事情&#xff0c;比如用户在网页上单击一个按钮 事件监听:就是让程序检测是否有事件产生&#xff0c;一旦有事件触发&#xff0c;就立即调用一个函…

金仕达与 DolphinDB 建立深度合作,共筑 FICC 科技创新新篇章

从“关起门做交易”到“打开门做服务”&#xff0c;国内 FICC 业务正经历从自营到市场化服务的转变&#xff0c;借助数据分析、算法交易等技术的快速发展&#xff0c;交易团队能够更加主动地发现市场需求&#xff0c;为不同客群提供更好的做市业务&#xff0c;FICC 交易电子化已…

打造智能汽车微服务系统平台:架构的设计与实现

随着智能汽车技术的飞速发展&#xff0c;微服务架构在汽车行业中的应用越来越广泛。采用微服务架构可以使汽车系统更加灵活、可扩展&#xff0c;并且有利于快速推出新功能和服务。本文将从设计原则、关键技术、数据安全等方面&#xff0c;介绍如何搭建智能汽车微服务系统平台架…

【Python】FastAPI 项目创建 与 Docker 部署

文章目录 前言&需求描述1. 本地FastAPI1.1 Python 环境准备1.2 本地 Pycharm 创建FastAPI项目 2. Python FastAPI 部署2.1 服务器配置Python环境2.2.1 下载与配置Git、Pyenv等工具2.2.2 下载与配置Python 2.2 FastAPI 打包成镜像2.2.1 项目准备所需环境文件2.2.2 编写Docke…

AI智能分析网关V4车辆违停算法在园区场景中的应用及特点

随着城市化进程的加速&#xff0c;车辆违停问题愈发严重&#xff0c;给城市交通带来了极大的困扰。为了解决这一问题&#xff0c;AI技术逐渐被应用于车辆违停的检测中。AI检测算法在车辆违停方面的应用&#xff0c;主要是通过计算机视觉技术&#xff0c;对道路上的车辆进行实时…

智慧灌区项目案例(甘肃省兰州市某重点灌区)

​甘肃省兰州市某重点灌区自上个世纪80年代建成后,灌溉面积达到30万亩,对推动当地农业发展发挥了重要作用。但长期以来,该灌区的水利管理仍主要依靠人工统计记录,缺乏实时监测和精细化管理。为实现灌区管理的现代化升级,甘肃水利局委托星创易联公司设计实施水利信息化项目。 项…

【Python笔记-设计模式】状态模式

一、说明 状态模式是一种行为设计模式&#xff0c;用于解决对象在不同状态下具有不同行为 (一) 解决问题 在对象行为根据对象状态而改变时&#xff0c;规避使用大量的条件语句来判断对象的状态&#xff0c;提高系统可维护性 (二) 使用场景 当对象的行为取决于其状态&#…

C#使用iText7将多个PDF文档合并为单个文档

使用HtmlAgilityPack抓取并分析网页内容&#xff0c;然后再调用PuppeteerSharp将网页生成PDF文件&#xff0c;最终的成果如下图所示&#xff0c;得到将近120个pdf文档。能看&#xff0c;但是不方便&#xff0c;需要逐个打开文档才能看到所需的内容&#xff0c;最好能将这些文档…

浅谈 Linux 网络编程 socket

文章目录 socket 介绍 socket 介绍 socket 被翻译成 网络套接字&#xff0c;这个名字实在是不好理解&#xff0c;我更愿意称为"插槽"。 忽略 socket 的中文名&#xff0c;先无脑记住两个规则&#xff1a; ① 记住&#xff0c;一个文件描述符(fd) 指向一个 socket&…

GPT-SoVITS音色克隆-模型训练步骤

GPT-SoVITS音色克隆-模型训练步骤 GPT-SoVITS模型源码一个简单的TTS后端项目 基于模型部署和训练教程&#xff0c;语雀 模型部署和训练教程 启动模型训练的主页面 1. 切到模型路径 /psycheEpic/GPT-SoVITS进入Python虚拟环境&#xff0c;并挂起执行python脚本 conda activ…

机器学习(II)--样本不平衡

现实中&#xff0c;样本&#xff08;类别&#xff09;样本不平衡&#xff08;class-imbalance&#xff09;是一种常见的现象&#xff0c;如&#xff1a;金融欺诈交易检测&#xff0c;欺诈交易的订单样本通常是占总交易数量的极少部分&#xff0c;而且对于有些任务而言少数样本更…