【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:

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

「MySQL」基本操作类型

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;数据库 &#x1f387;欢迎点赞收藏加关注哦&#xff01; 数据库的操作 创建、显示数据库 使用 create 创建一个数据库 create database goods;然后可以用 show databases 来查看已经创建的数…

人大金仓与mysql的差异与替换

人大金仓中不能使用~下面的符号&#xff0c;字段中使用”&#xff0c;无法识别建表语句 创建表时语句中只定义字段名.字段类型.是否是否为空 Varchar类型改为varchar&#xff08;长度 char&#xff09; Int(0) 类型为int4 定义主键&#xff1a;CONSTRAINT 键名 主键类型&#x…

32单片机基础:TIM输出比较

这个输出比较功能是非常重要的&#xff0c;它主要是用来输出PWM波形,PWM波形又是驱动电机的必要条件&#xff0c;所以你如果想用STM32做一些有电机的项目&#xff0c;比如智能车&#xff0c;机器人等。 IC: Input Capture 输入捕获 CC:Capture/Compare一般表示输入捕获和输出…

爱心商城|爱心商城系统|基于Springboot的爱心商城系统设计与实现(源码+数据库+文档)

爱心商城系统目录 目录 基于Springboot的爱心商城系统设计与实现 一、前言 二、系统功能设计 三、系统功能设计 1、商品管理 2、捐赠管理 3、公告管理 4、公告类型管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#x…

spring boot学习第十三篇:使用spring security控制权限

该文章同时也讲到了如何使用swagger。 1、pom.xml文件内容如下&#xff1a; <?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-instanc…

华为配置WLAN高密业务示例

配置WLAN高密业务示例 组网图形 图1 配置高密WLAN环境网络部署组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件 业务需求 体育场由于需要接入用户数量很大&#xff0c;AP间部署距离较小&#xff0c;因此AP间的干扰较大&#xff0c;可能导致用户上网网…

PostgreSQL从入门到精通教程 - 第45讲:poc-tpcc测试

PostgreSQL从小白到专家&#xff0c;是从入门逐渐能力提升的一个系列教程&#xff0c;内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容&#xff0c;希望对热爱PG、学习PG的同学们有帮助&#xff0c;欢迎持续关注CUUG PG技术大讲堂。 第45讲&#…

【知识整理】Git 使用实践问题整理

问题1、fatal: refusing to merge unrelated histories 一、Git 的报错 fatal: refusing to merge unrelated histories 新建了一个仓库之后&#xff0c;把本地仓库进行关联提交、拉取的时候&#xff0c;出现了如下错误&#xff1a; fatal: master does not appear to be a g…

状态码转文字!!!(表格数字转文字)

1、应用场景&#xff1a;在我们的数据库表中经常会有status这个字段&#xff0c;这个字段经常表示此类商品的状态&#xff0c;例如&#xff1a;0->删除&#xff0c;1->上架&#xff0c;0->下架&#xff0c;等等。 2、我们返回给前端数据时&#xff0c;如果在页面显示0…

C语言实现21点游戏【单人模式,双人模式,单-多电脑模式】,21点又名黑杰克(英文:Blackjack)

项目背景&#xff1a; 21点又名黑杰克&#xff08;英文&#xff1a;Blackjack&#xff09; &#xff0c;起源于法国&#xff0c;已流传到世界各地。21点&#xff0c;是一种使用扑克牌玩的赌博游戏。亦是唯一一种在赌场中可以在概率中战胜庄家的一种赌博游戏。 现在在世界各地…

计算机网络原理--传输层

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 TCP/IP五层&#xff08;或四层&#xff09;模型 传输层 TCP和UDP的区别 UDP协议 校验和 如何…

【Unity】如何设置Unity脚本的执行顺序?

在 Unity 编辑器中设置脚本执行顺序 在 Unity 中&#xff0c;如果有多个脚本&#xff0c;并且它们之间的执行顺序很重要&#xff0c;可以通过编辑器设置来确保它们按照自己期望的顺序执行。这对于确保某些脚本在其他脚本之前执行非常有用。在这篇文章中&#xff0c;将向会展示如…

Kubernetes IoTDB系列 | IoTDB数据库同步|IoTDB数据库高可用 | v1.3.0

目录 一、介绍二、应用场景三、IoTDB 数据库搭建四、数据同步一、介绍 IoTDB 数据同步功能可以将 IoTDB 的数据传输到另一个数据平台,我们将一个数据同步任务称为 Pipe。 一个 Pipe 包含三个子任务(插件): 抽取(Extract)处理(Process)发送(Connect)Pipe 允许用户自…

【MySQL】学习多表查询和笛卡尔积 - 副本

](https://img-blog.csdnimg.cn/21dd41dce63a4f2da07b9d879ad0120b.png#pic_center) ??个人主页: ??热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ??个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-N8PeTKG6uLu4bJuM {font-family:“trebuchet ms”,…

强化学习Agent系列(二)——PyGame虚拟环境创建与Python 贪吃蛇Agent制作实战教学

文章目录 一、前言二、gymnasium 简单虚拟环境创建1、gymnasium介绍2、gymnasium 贪吃蛇简单示例 三、基于gymnasium创建的虚拟环境训练贪吃蛇Agent1、虚拟环境2、虚拟环境注册3、训练程序4、模型测试 三、卷积虚拟环境1、卷积神经网络虚拟环境2、训练代码 一、前言 大家好&am…

300分钟吃透分布式缓存(拉钩教育总结)

开篇寄语 开篇寄语&#xff1a;缓存&#xff0c;你真的用对了吗&#xff1f; 你好&#xff0c;我是你的缓存老师陈波&#xff0c;可能大家对我的网名 fishermen 会更熟悉。 我是资深老码农一枚&#xff0c;经历了新浪微博从起步到当前月活数亿用户的大型互联网系统的技术演进…

NebulaGraph入门

感谢阅读 官方文档链接NebulaGraph简介nGQLnGQL简介占位标识符和占位符值注释实列大小写区分关键字 基本概念以及相关代码实现补充说明图空间语法以及列子创建克隆官方示例代码(创建并克隆)USE语句指定图空间时查看所有SPACESPACE详情CLEAR SPACE删库跑路&#xff08;看玩笑的说…

C语言:字符函数 字符串函数 内存函数

C语言&#xff1a;字符函数 & 字符串函数 & 内存函数 字符函数字符分类函数字符转换函数tolowertoupper 字符串函数strlenstrcpystrcatstrcmpstrstrstrtok 内存函数memcpymemmovememsetmemcmp 字符函数 顾名思义&#xff0c;字符函数就是作用于字符的函数&#xff0c;…

3dgs学习(二)—— 3d高斯与协方差矩阵及其几何意义

协方差矩阵与3d高斯 3d高斯与椭球与协方差矩阵 3d高斯&#xff0c;及3维空间内的正态分布。 通过一元正态分布的坐标系图像不难想象&#xff0c;3维空间中的正态分布点集中在一片椭球空间中&#xff0c;各方向长轴取决于各方向正态分布的方差。 而协方差矩阵通过计算多元之…

好物周刊#42:国产项目管理软件

https://github.com/cunyu1943 村雨遥的好物周刊&#xff0c;记录每周看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;每周五发布。 一、项目 1. 菠萝博客 基于 Java 的菠萝博客系统&#xff0c;简单易部署&#xff0c;精致主题&#xff0c;贴心服务&#xf…