Maven高级-分模块开发依赖管理

Maven高级-分模块开发&依赖管理

  • 1,分模块开发
    • 1.1 分模块开发设计
    • 1.2 分模块开发实现
      • 1.2.1 环境准备
      • 1.2.2 抽取domain层
        • 步骤1:创建新模块
        • 步骤2:项目中创建domain包
        • 步骤3:删除原项目中的domain包
        • 步骤4:建立依赖关系
        • 步骤5:编译`maven_02_ssm`项目
        • 步骤6:将项目安装本地仓库
      • 1.2.3 抽取Dao层
        • 步骤1:创建新模块
        • 步骤2:项目中创建dao包
        • 步骤3:删除原项目中的dao包
        • 步骤4:将项目安装到本地仓库
      • 1.2.4 运行测试并总结
  • 2,依赖管理
    • 2.1 依赖传递与冲突问题
    • 2.2 可选依赖和排除依赖
      • 方案一:可选依赖
      • 方案二:排除依赖

目标

  • 理解并实现分模块开发

1,分模块开发


1.1 分模块开发设计

(1)按照功能拆分

我们现在的项目都是在一个模块中,比如前面的SSM整合开发。虽然这样做功能也都实现了,但是也存在了一些问题,我们拿银行的项目为例来聊聊这个事。

  • 网络没有那么发达的时候,我们需要到银行柜台或者取款机进行业务操作
  • 随着互联网的发展,我们有了电脑以后,就可以在网页上登录银行网站使用U盾进行业务操作
  • 再来就是随着智能手机的普及,我们只需要用手机登录APP就可以进行业务操作

上面三个场景出现的时间是不相同的,如果非要把三个场景的模块代码放入到一个项目,那么当其中某一个模块代码出现问题,就会导致整个项目无法正常启动,从而导致银行的多个业务都无法正常班理。所以我们会按照功能将项目进行拆分。

(2)按照模块拆分

比如电商的项目中,有订单和商品两个模块,订单中需要包含商品的详细信息,所以需要商品的模型类,商品模块也会用到商品的模型类,这个时候如果两个模块中都写模型类,就会出现重复代码,后期的维护成本就比较高。我们就想能不能将它们公共的部分抽取成一个独立的模块,其他模块要想使用可以像添加第三方jar包依赖一样来使用我们自己抽取的模块,这样就解决了代码重复的问题,这种拆分方式就说我们所说的按照模块拆分。

经过两个案例的分析,我们就知道:

  • 将原始模块按照功能拆分成若干个子模块,方便模块间的相互调用,接口共享。

刚刚我们说了可以将domain层进行拆分,除了domain层,我们也可以将其他的层也拆成一个个对立的模块,如:

这样的话,项目中的每一层都可以单独维护,也可以很方便的被别人使用。关于分模块开发的意义,我们就说完了,说了这么多好处,那么该如何实现呢?


1.2 分模块开发实现

前面我们已经完成了SSM整合,接下来,咱们就基于SSM整合的项目来实现对项目的拆分。


1.2.1 环境准备

资料\maven_02_ssm部署到IDEA中,将环境快速准备好,部署成功后,项目的格式如下:


1.2.2 抽取domain层


步骤1:创建新模块

创建一个名称为maven_03_pojo的jar项目,为什么项目名是从02到03这样创建,原因后面我们会提到,这块的名称可以任意。


步骤2:项目中创建domain包

maven_03_pojo项目中创建com.itheima.domain包,并将maven_02_ssm中Book类拷贝到该包中


步骤3:删除原项目中的domain包

删除后,maven_02_ssm项目中用到Book的类中都会有红色提示,如下:

**说明:**出错的原因是maven_02_ssm中已经将Book类删除,所以该项目找不到Book类,所以报错

要想解决上述问题,我们需要在maven_02_ssm中添加maven_03_pojo的依赖。


步骤4:建立依赖关系

maven_02_ssm项目的pom.xml添加maven_03_pojo的依赖

<dependency>
    <groupId>com.itheima</groupId>
    <artifactId>maven_03_pojo</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

因为添加了依赖,所以在maven_02_ssm中就已经能找到Book类,所以刚才的报红提示就会消失。


步骤5:编译maven_02_ssm项目

编译maven_02_ssm你会在控制台看到如下错误

错误信息为:不能解决maven_02_ssm项目的依赖问题,找不到maven_03_pojo这个jar包。

为什么找不到呢?

原因是Maven会从本地仓库找对应的jar包,但是本地仓库又不存在该jar包所以会报错。

在IDEA中是有maven_03_pojo这个项目,所以我们只需要将maven_03_pojo项目安装到本地仓库即可。


步骤6:将项目安装本地仓库

将需要被依赖的项目maven_03_pojo,使用maven的install命令,把其安装到Maven的本地仓库中。

安装成功后,在对应的路径下就看到安装好的jar包

**说明:**具体安装在哪里,和你们自己电脑上Maven的本地仓库配置的位置有关。

当再次执行maven_02_ssm的compile的命令后,就已经能够成功编译。


1.2.3 抽取Dao层


步骤1:创建新模块

创建一个名称为maven_04_dao的jar项目


步骤2:项目中创建dao包

maven_04_dao项目中创建com.itheima.dao包,并将maven_02_ssm中BookDao类拷贝到该包中

maven_04_dao中会有如下几个问题需要解决下:

  • 项目maven_04_dao的BookDao接口中Book类找不到报错

    • 解决方案在maven_04_dao项目的pom.xml中添加maven_03_pojo项目

      <dependencies>
          <dependency>
              <groupId>com.itheima</groupId>
              <artifactId>maven_03_pojo</artifactId>
              <version>1.0-SNAPSHOT</version>
          </dependency>
      </dependencies>
      
  • 项目maven_04_dao的BookDao接口中,Mybatis的增删改查注解报错

    • 解决方案在maven_04_dao项目的pom.xml中添加mybatis的相关依赖

      <dependencies>
          <dependency>
              <groupId>org.mybatis</groupId>
              <artifactId>mybatis</artifactId>
              <version>3.5.6</version>
          </dependency>
      
          <dependency>
              <groupId>mysql</groupId>
              <artifactId>mysql-connector-java</artifactId>
              <version>5.1.47</version>
          </dependency>
      </dependencies>
      

步骤3:删除原项目中的dao包

删除Dao包以后,因为maven_02_ssm中的BookServiceImpl类中有使用到Dao的内容,所以需要在maven_02_ssm的pom.xml添加maven_04_dao的依赖

<dependency>
    <groupId>com.itheima</groupId>
    <artifactId>maven_04_dao</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

此时在maven_02_ssm项目中就已经添加了maven_03_pojomaven_04_dao

再次对maven_02_ssm项目进行编译,又会报错,如下:

和刚才的错误原因是一样的,maven在仓库中没有找到maven_04_dao,所以此时我们只需要将maven_04_dao安装到Maven的本地仓库即可。


步骤4:将项目安装到本地仓库

将需要被依赖的项目maven_04_dao,使用maven的install命令,把其安装到Maven的本地仓库中。

安装成功后,在对应的路径下就看到了安装好对应的jar包

当再次执行maven_02_ssm的compile的指令后,就已经能够成功编译。


1.2.4 运行测试并总结

将抽取后的项目进行运行,测试之前的增删改查功能依然能够使用。

所以对于项目的拆分,大致会有如下几个步骤:

(1) 创建Maven模块

(2) 书写模块代码

分模块开发需要先针对模块功能进行设计,再进行编码。不会先将工程开发完毕,然后进行拆分。拆分方式可以按照功能拆也可以按照模块拆。

(3)通过maven指令安装模块到本地仓库(install 指令)

团队内部开发需要发布模块功能到团队内部可共享的仓库中(私服),私服我们后面会讲解。


2,依赖管理

我们现在已经能把项目拆分成一个个独立的模块,当在其他项目中想要使用独立出来的这些模块,只需要在其pom.xml使用标签来进行jar包的引入即可。

其实就是依赖,关于依赖管理里面都涉及哪些内容,我们就一个个来学习下:

  • 依赖传递
  • 可选依赖
  • 排除依赖

我们先来说说什么是依赖:

依赖指当前项目运行所需的jar,一个项目可以设置多个依赖。

格式为:

<!--设置当前项目所依赖的所有jar-->
<dependencies>
    <!--设置具体的依赖-->
    <dependency>
        <!--依赖所属群组id-->
        <groupId>org.springframework</groupId>
        <!--依赖所属项目id-->
        <artifactId>spring-webmvc</artifactId>
        <!--依赖版本号-->
        <version>5.2.10.RELEASE</version>
    </dependency>
</dependencies>

2.1 依赖传递与冲突问题

回到我们刚才的项目案例中,打开Maven的面板,你会发现:

在项目所依赖的这些jar包中,有一个比较大的区别就是有的依赖前面有箭头>,有的依赖前面没有。

那么这个箭头所代表的含义是什么?

打开前面的箭头,你会发现这个jar包下面还包含有其他的jar包

你会发现有两个maven_03_pojo的依赖被加载到Dependencies中,那么maven_04_dao中的maven_03_pojo能不能使用呢?

要想验证非常简单,只需要把maven_02_ssm项目中pom.xml关于maven_03_pojo的依赖注释或删除掉

在Dependencies中移除自己所添加maven_03_pojo依赖后,打开BookServiceImpl的类,你会发现Book类依然存在,可以被正常使用

在这里插入图片描述

这个特性其实就是我们要讲解的依赖传递

依赖是具有传递性的:

说明: A代表自己的项目;B,C,D,E,F,G代表的是项目所依赖的jar包;D1和D2 E1和E2代表是相同jar包的不同版本

(1) A依赖了B和C,B和C有分别依赖了其他jar包,所以在A项目中就可以使用上面所有jar包,这就是所说的依赖传递

(2) 依赖传递有直接依赖和间接依赖

  • 相对于A来说,A直接依赖B和C,间接依赖了D1,E1,G,F,D2和E2
  • 相对于B来说,B直接依赖了D1和E1,间接依赖了G
  • 直接依赖和间接依赖是一个相对的概念

(3)因为有依赖传递的存在,就会导致jar包在依赖的过程中出现冲突问题,具体什么是冲突?Maven是如何解决冲突的?

这里所说的依赖冲突是指项目依赖的某一个jar包,有多个不同的版本,因而造成类包版本冲突。

情况一: 在maven_02_ssm的pom.xml中添加两个不同版本的Junit依赖:

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

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

通过对比,会发现一个结论

  • 特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配置的。

情况二: 路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高

  • A通过B间接依赖到E1
  • A通过C间接依赖到E2
  • A就会间接依赖到E1和E2,Maven会按照层级来选择,E1是2度,E2是3度,所以最终会选择E1

情况三: 声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的

  • A通过B间接依赖到D1
  • A通过C间接依赖到D2
  • D1和D2都是两度,这个时候就不能按照层级来选择,需要按照声明来,谁先声明用谁,也就是说B在C之前声明,这个时候使用的是D1,反之则为D2

但是对应上面这些结果,大家不需要刻意去记它。因为不管Maven怎么选,最终的结果都会在Maven的Dependencies面板中展示出来,展示的是哪个版本,也就是说它选择的就是哪个版本,如:

如果想更全面的查看Maven中各个坐标的依赖关系,可以点击Maven面板中的show Dependencies

在这个视图中就能很明显的展示出jar包之间的相互依赖关系。


2.2 可选依赖和排除依赖

依赖传递介绍完以后,我们来思考一个问题,

  • maven_02_ssm 依赖了 maven_04_dao
  • maven_04_dao 依赖了 maven_03_pojo
  • 因为现在有依赖传递,所以maven_02_ssm能够使用到maven_03_pojo的内容
  • 如果说现在不想让maven_02_ssm依赖到maven_03_pojo,有哪些解决方案?

**说明:**在真实使用的过程中,maven_02_ssm中是需要用到maven_03_pojo的,我们这里只是用这个例子描述我们的需求。因为有时候,maven_04_dao出于某些因素的考虑,就是不想让别人使用自己所依赖的maven_03_pojo。


方案一:可选依赖

  • 可选依赖指对外隐藏当前所依赖的资源—不透明

maven_04_dao的pom.xml,在引入maven_03_pojo的时候,添加optional

<dependency>
    <groupId>com.itheima</groupId>
    <artifactId>maven_03_pojo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--可选依赖是隐藏当前工程所依赖的资源,隐藏后对应资源将不具有依赖传递-->
    <optional>true</optional>
</dependency>

此时BookServiceImpl就已经报错了,说明由于maven_04_dao将maven_03_pojo设置成可选依赖,导致maven_02_ssm无法引用到maven_03_pojo中的内容,导致Book类找不到。


方案二:排除依赖

  • 排除依赖指主动断开依赖的资源,被排除的资源无需指定版本—不需要

前面我们已经通过可选依赖实现了阻断maven_03_pojo的依赖传递,对于排除依赖,则指的是已经有依赖的事实,也就是说maven_02_ssm项目中已经通过依赖传递用到了maven_03_pojo,此时我们需要做的是将其进行排除,所以接下来需要修改maven_02_ssm的pom.xml

<dependency>
    <groupId>com.itheima</groupId>
    <artifactId>maven_04_dao</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--排除依赖是隐藏当前资源对应的依赖关系-->
    <exclusions>
        <exclusion>
            <groupId>com.itheima</groupId>
            <artifactId>maven_03_pojo</artifactId>
        </exclusion>
    </exclusions>
</dependency>

这样操作后,BookServiceImpl中的Book类一样也会报错。

当然exclusions标签带s说明我们是可以依次排除多个依赖到的jar包,比如maven_04_dao中有依赖junit和mybatis,我们也可以一并将其排除。

<dependency>
    <groupId>com.itheima</groupId>
    <artifactId>maven_04_dao</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--排除依赖是隐藏当前资源对应的依赖关系-->
    <exclusions>
        <exclusion>
            <groupId>com.itheima</groupId>
            <artifactId>maven_03_pojo</artifactId>
        </exclusion>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
        </exclusion>
    </exclusions>
</dependency>

介绍我这两种方式后,简单来梳理下,就是

  • A依赖B,B依赖C,C通过依赖传递会被A使用到,现在要想办法让A不去依赖C
  • 可选依赖是在B上设置<optional>,A不知道有C的存在,
  • 排除依赖是在A上设置<exclusions>,A知道有C的存在,主动将其排除掉。

学习笔记 from 黑马程序员

By – Suki 2023/4/6

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

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

相关文章

Memory Map

主要介绍AM64x的MSRAM和DDR的内存分布&#xff1a; MSRAM:总共2MB,被分成8个banks,每个256KB。 首先了解一下&#xff0c;两种Domain: In TI documentation, the MCU Domain may be referred to as “M4FSS Island”, “MCU Island”, “MCU Channel”, or “MCU Subsystem…

Redis分布式缓存

文章目录一、 概述1. 单节点Redis存在的问题2. 单节点Redis问题针对解决方案二、Redis持久化1. RDB持久化2.RDB异步持久化原理介绍3. AOF持久化4. ROB和AOF对比三、Redis主从架构1. 搭建主从架构2. 主从数据同步原理四、Redis哨兵1. 哨兵的作用和原理2.搭建哨兵集群3. RedisTem…

Linux 操作系统原理 — RSS 多队列网卡

目录 文章目录目录RSS 多队列网卡RSS 技术实现原理RSS FilterRSS HASH硬中断信号绑定ethtool 操作指令RSS 多队列网卡 在以往&#xff0c;一张 NIC 只具有一个 Rx Queue&#xff0c;对应一个 CPU Core 来进行收包处理。在多核时代&#xff0c;为了充分利用 Multi-CPU Cores&am…

如何使用pandas提取含有指定字符串

这里写自定义目录标题name age state point0 Alice 24 NY 641 Bob 42 CA 922 Charlie 18 CA 70name age state point0 Alice 24 NY 642 Charlie 18 CA 700 False1 True2 TrueName: state, dtype: boolname age state point1 Bob 42 CA 922 Charlie 18 CA 700 True1 False2 True…

tmall.service.settleadjustment.modify( 修改结算调整单 )

&#xffe5;开放平台免费API必须用户授权 提供给服务商在对结算有异议时&#xff0c;发起结算调整单。 通过说明调整单ID&#xff0c;调整费用值&#xff0c;调整原因进行结算调整单修改。 公共参数 请求地址: 公共请求参数: 公共响应参数: 请求参数 响应参数 点击获取key和…

MyBatisPlus-DML编程控制

MyBatisPlus-DML编程控制4&#xff0c;DML编程控制4.1 id生成策略控制知识点1&#xff1a;TableId4.1.1 环境构建4.1.2 代码演示AUTO策略步骤1:设置生成策略为AUTO步骤2:删除测试数据并修改自增值步骤3:运行新增方法INPUT策略步骤1:设置生成策略为INPUT步骤2:添加数据手动设置I…

【hello Linux】Linux权限管理

目录 1.shell命令以及运行原理 2. Linux权限的概念 3. Linux权限管理 3.1 文件访问者的分类 3.2 文件类型 3.3 访问权限 3.4 访问权限的表示方法 4. 访问权限的相关设置 4.1 chmod命令&#xff1a;修改权限 4.2 chown命令&#xff1a;修改文件的拥有者 4.3 chgrp 命令&#xff…

idea中的项目上传gitee

1.把gitee插件安装找重启idea 2.打开gitee网站从设置->私有令牌 获取token信息完成登录 复制到idea中点击log in 点击ok 3.把项目转为git管理 4.上传到gitee 5.去刷新gitee仓库此时就会发现多了一个我们的项目 以下是拷贝新项目到idea操作 http://t.csdn.cn/ycnSX

【Ansys】什么软件模块是DS,它和workbench、mechanical的区别在哪里?

一、DesignSpace和workbench 早期的Workbench称之为DesignSpace&#xff0c;更偏向于建模。 现在DS是license的一种&#xff0c;而分析的模块在11中称之为Simulation&#xff08;Design Simulation&#xff09;&#xff0c;在12中改名为Mechanical。 所以&#xff0c;你可以…

IFPUG功能点度量4:度量事务功能

一、基本概念 1、事务功能 事务功能是处理数据功能的基本过程。 每个事务功能都是一个基本过程。 事务功能由多个逻辑处理来完成。 事务功能包含三种类型&#xff1a;EI、EO、EQ 2、基本过程 一个基本过程是由一个逻辑处理或者多个逻辑处理来完成的。 如何识别&#xf…

【备考技巧】系统集成(案例分析题)并不难

案例分析考题分析&#xff1a; 正常情况下四道题&#xff0c;计算题20分左右&#xff0c;剩余三道分析题每题15-20分左右。 ☆案例分析题&#xff1a; 从整体管理、范围管理、质量管理、人力资源管理、合同管理&采购管理、配置管理、风险管理、进度管理、成本管理中出简答题…

Jvm学习笔记(二)GC

GC 垃圾收集(GC)起源于Lisp&#xff0c;远比Java的历史更久&#xff0c;它主要思考了三件事情&#xff1a; 哪些内存需要回收&#xff1f;什么时候回收&#xff1f;如何回收&#xff1f; 本章就根据这三个点进行分析。 哪些内存需要回收&#xff1f; 在java堆中存放着无数的…

Mac浏览器无法上网但可以用微信等

可以使用微信QQ等&#xff0c;但是浏览器无法上网&#xff0c;Mac浏览器无法上网怎么办&#xff0c;Mac浏览器无法上网但可以用微信等&#xff08;百度了一下&#xff0c;没有找到原因是为什么&#xff0c;只找到了解决方法&#xff0c;记录一下&#xff09; 1.首先我们打开Ma…

Centos安装docker以及通过docker部署Mysql,照做就行!

1.安装docker 1.1给虚拟机联网&#xff08;反斜杠带表该语句没写完&#xff09; yum install -y yum-utils \device-mapper-persistent-data \lvm2 --skip-broken 1.2更新本地文件镜像 # 设置docker镜像源 yum-config-manager \--add-repo \https://mirrors.aliyun.com/doc…

【Python_Selenium学习笔记(四)】基于Selenium模块实现键盘操作

基于Selenium模块实现键盘操作 前言 在 Selenium 模块中&#xff0c;提供了一个 Keys 类&#xff0c;来处理键盘操作&#xff1b; 在 Selenium 模块中&#xff0c;使用 send_keys() 方法&#xff0c;来模拟键盘输入&#xff0c; 此篇文章主要介绍如何使用 Keys 类 和 send_ke…

vue请求本地JSON文件(注意路径 否则会404)

npm i axios // main.jsimport axios from "axios";Vue.prototype.$axios axios; //全局注册&#xff0c;使用方法为:this.$axios...vue/cli 2 json文件存放目录为 根目录下static/json/aaa.json // 使用getVideoData() {this.$axios.create({baseURL: "&quo…

springboot 部署k8s(二)

系列文章目录 目录 系列文章目录 前言 操作步骤 1.springboot.yaml文件 2.查看deployment 3.查看service服务 4.验证服务 总结 前言 springboot 部署到k8s 上。里面涉及了deployment, Service, NodePort. 操作步骤 1.springboot.yaml文件 apiVersion: apps/v1 kind: …

codeblocks20.3配置wxWidget3.2.2.1

codeblocks20.3 # 英文版自带gcc810&#xff0c;不汉化 wxWidget3.2.2.1 github下载源码 win11专业版 1.下载wxWidget3.2.2.1 源码 2.下载后解压到一个目录中&#xff0c;不要含中文和空格。我放在&#xff1a;d:\wxWidget3.2.2.1 3.打开终端cd build/msw 4.编译wxWidgets 为 …

本行卡转账基本流程说明

1、业务大致流程 2、基本业务描述 大概流程说明&#xff1a;&#xff08;牵涉到调用硬件、不便多说&#xff09; 用户插卡后、选择转账交易、依次输入转入账户卡号和转账金额后&#xff0c;用户确定转账信息&#xff1b;转账交易发送前&#xff1a;需要根据插卡账户信息和转账…

Java基础(四)数组

1. 数组的概述 1.1 为什么需要数组 需求分析1&#xff1a; 需要统计某公司50个员工的工资情况&#xff0c;例如计算平均工资、找到最高工资等。用之前知识&#xff0c;首先需要声明50个变量来分别记录每位员工的工资&#xff0c;这样会很麻烦。因此我们可以将所有的数据全部存…