【Maven从入门到入土】

news2024/11/21 2:23:59

文章目录

  • 1.Maven
    • 1.1 初识Maven
      • 依赖管理:
      • 统一项目结构 :
      • 项目构建 :
    • 1.2 Maven概述
      • 1.2.1 Maven模型
      • 1.2.2 Maven仓库
      • 1.2.3 Maven安装
    • 1.3 IDEA集成Maven
      • 1.3.1 配置Maven环境
        • 1.3.1.1 当前工程设置
        • 1.3.1.2 全局设置
      • 1.3.2 Maven项目
        • 1.3.2.1 创建Maven项目
        • 1.3.2.2 POM配置详解
        • 3.2.3 Maven坐标详解
      • 1.3.3 导入Maven项目
    • 1.4 依赖管理
      • 1.4.1 依赖配置
      • 1.4.2 依赖传递
        • 1.4.2.1 依赖具有传递性
        • 1.4.2.2 排除依赖
      • 1.4.3 依赖范围
      • 1.4.4 生命周期
        • 1.4.4.1 介绍
        • 1.4.4.2 执行
    • 1.5 附录
      • 1.5.1 更新依赖索引
      • 1.5.2 清理maven仓库
  • 2. Maven高级
    • 2.1 分模块设计与开发
      • 2.1.1 介绍
      • 2.1.2 实践
        • 2.1.2.1 分析
        • 2.1.2.2 实现
      • 2.1.3 总结
    • 2.2 继承与聚合
      • 2.2.1 继承
        • 2.2.1.1 继承关系
          • 2.2.1.1.1 思路分析
          • 2.2.1.1.2 实现
        • 2.2.1.2 版本锁定
          • 2.2.1.2.1 场景
          • 2.2.1.2.2 介绍
          • 2.2.1.2.3 实现
          • 2.2.1.2.4 属性配置
      • 2.2.2 聚合
        • 2.2.2.1 介绍
        • 2.2.2.2 实现
      • 2.2.3 继承与聚合对比
    • 2.3 私服
      • 2.3.1 场景
      • 2.3.2 介绍
      • 2.3.3 资源上传与下载
        • 2.3.3.1 步骤分析
        • 2.3.3.2 具体操作

1.Maven

1.1 初识Maven

Maven是Apache旗下的一个开源项目,是一款用于管理和构建java项目的工具。

官网:https://maven.apache.org/

Apache 软件基金会,成立于1999年7月,是目前世界上最大的最受欢迎的开源软件基金会,也是一个专门为支持开源项目而生的非盈利性组织。

开源项目:https://www.apache.org/index.html#projects-list

Maven的三个功能:

  1. 依赖管理
  2. 统一项目结构
  3. 项目构建

依赖管理:

  • 方便快捷的管理项目依赖的资源(jar包),避免版本冲突问题
    请添加图片描述

使用maven进行项目依赖(jar包)管理可以解决这个问题只需要在maven项目的pom.xml文件中,添加一段如下图所示的配置即可实现。
请添加图片描述

统一项目结构 :

  • 提供标准、统一的项目结构

在项目开发中,当使用不同的开发工具 (如:Eclipse、Idea),创建项目工程时:
请添加图片描述

若创建的是一个maven工程,是可以帮我们自动生成统一、标准的项目目录结构:
请添加图片描述

具体的统一结构如下:
请添加图片描述

目录说明:

  • src/main/java: java源代码目录
  • src/main/resources: 配置文件信息
  • src/test/java: 测试代码
  • src/test/resources: 测试配置文件信息

项目构建 :

  • maven提供了标准的、跨平台(Linux、Windows、MacOS) 的自动化项目构建方式
    请添加图片描述

开发了一套系统,代码需要进行编译、测试、打包、发布,这些操作如果需要反复进行就显得特别麻烦,而Maven提供了一套简单的命令来完成项目构建。
请添加图片描述

综上所述:Maven是一款管理和构建java项目的工具

1.2 Maven概述

1.2.1 Maven模型

  • 项目对象模型 (Project Object Model)
  • 依赖管理模型(Dependency)
  • 构建生命周期/阶段(Build lifecycle & phases)

1). 构建生命周期/阶段(Build lifecycle & phases)
请添加图片描述

以上图中紫色框起来的部分,就是用来完成标准化构建流程 。当需要编译时,Maven就提供一个编译插件供使用;当需要打包时,Maven就提供一个打包插件供使用……。

2). 项目对象模型 (Project Object Model)
请添加图片描述

以上图中紫色框起来的部分属于项目对象模型,就是将项目抽象成一个对象模型,有自己专属的坐标,如下图所示是一个Maven项目:
请添加图片描述

坐标,就是资源(jar包)的唯一标识,通过坐标可以定位到所需资源(jar包)位置
请添加图片描述

3). 依赖管理模型(Dependency)
请添加图片描述

以上图中紫色框起来的部分属于依赖管理模型,是使用坐标来描述当前项目依赖哪些第三方jar包
请添加图片描述

之前项目中需要jar包时,就直接把jar包复制到项目下的lib目录,而现在修改pom.xml文件中的坐标通过Maven仓库找到所要的jar包文件

1.2.2 Maven仓库

仓库:用于存储资源,管理各种jar包,仓库的本质就是一个目录(文件夹),这个目录被用来存储开发中所有依赖(就是jar包)和插件

Maven仓库分为:

  • 本地仓库:自己计算机上的一个目录(用来存储jar包)
  • 中央仓库:由Maven团队维护的全球唯一的。仓库地址:https://repo1.maven.org/maven2/
  • 远程仓库(私服):一般由公司团队搭建的私有仓库
    请添加图片描述

当项目中使用坐标引入对应依赖jar包后,首先会查找本地仓库中是否有对应的jar包

  • 如果有,则在项目直接引用

  • 如果没有,则去中央仓库中下载对应的jar包到本地仓库

如果还可以搭建远程仓库(私服),将来jar包的查找顺序则变为: 本地仓库 --> 远程仓库–> 中央仓库

1.2.3 Maven安装

下载地址:https://maven.apache.org/download.cgi

Maven安装配置步骤:

  1. 解压安装
  2. 配置仓库
  3. 配置Maven环境变量

1、解压 apache-maven-3.6.1-bin.zip(解压即安装)

安装后的目录结构如下:
请添加图片描述

  • bin目录 : 存放的是可执行命令。(mvn 命令重点关注)
  • conf目录 :存放Maven的配置文件。(settings.xml配置文件后期需要修改)
  • lib目录 :存放Maven依赖的jar包。(Maven也是使用java开发的,所以它也依赖其他的jar包)

2、配置本地仓库

  1. 在自己计算机上新一个目录(本地仓库,用来存储jar包)
    请添加图片描述

  2. 进入到conf目录下修改settings.xml配置文件

1). 使用超级记事本软件,打开settings.xml文件,定位到53行

2). 复制标签,粘贴到注释的外面(55行)

3). 复制之前新建的用来存储jar包的路径,替换掉标签体内容
请添加图片描述

3、配置阿里云私服

由于中央仓库在国外,所以下载jar包速度可能比较慢,而阿里公司提供了一个远程仓库,里面基本也都有开源项目的jar包。

进入到conf目录下修改settings.xml配置文件:

1). 使用notepad或者sublime等编辑软件,打开settings.xml文件,定位到160行左右

2). 在标签下为其添加子标签,内容如下:

<mirror>  
    <id>alimaven</id>  
    <name>aliyun maven</name>  
    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    <mirrorOf>central</mirrorOf>          
</mirror>

请添加图片描述

4、配置环境变量

Maven环境变量的配置类似于JDK环境变量配置一样

1). 在系统变量处新建一个变量MAVEN_HOME

  • MAVEN_HOME环境变量的值,设置为maven的解压安装目录
    请添加图片描述

2). 在Path中进行配置

  • PATH环境变量的值,设置为:%MAVEN_HOME%\bin
    请添加图片描述

3). 打开DOS命令提示符进行验证,出现如图所示表示安装成功

mvn -v

请添加图片描述

1.3 IDEA集成Maven

1.3.1 配置Maven环境

1.3.1.1 当前工程设置

1、选择 IDEA中 File => Settings => Build,Execution,Deployment => Build Tools => Maven
请添加图片描述
请添加图片描述

2、设置IDEA使用本地安装的Maven,并修改配置文件及本地仓库路径
请添加图片描述

  • Maven home path :指定当前Maven的安装目录
  • User settings file :指定当前Maven的settings.xml配置文件的存放路径
  • Local repository :指定Maven的本地仓库的路径 (如果指定了settings.xml, 这个目录会自动读取出来, 可以不用手动指定)

3、配置工程的编译版本为11

  • Maven默认使用的编译版本为5(版本过低)
    请添加图片描述

上述配置的maven环境,只是针对于当前工程的,如果再创建一个project,又恢复成默认的配置了。 要解决这个问题, 就需要配置全局的maven环境。

1.3.1.2 全局设置

1、进入到IDEA欢迎页面

  • 选择 IDEA中 File => close project
    请添加图片描述
    请添加图片描述

2、打开 All settings , 选择 Build,Execution,Deployment => Build Tools => Maven
请添加图片描述

3、配置工程的编译版本为11
请添加图片描述

这里所设置的maven的环境信息,并未指定任何一个project,此时设置的信息就属于全局配置信息。

1.3.2 Maven项目

1.3.2.1 创建Maven项目

1、创建一个空项目
请添加图片描述
请添加图片描述

2、创建模块,选择Maven,点击Next
请添加图片描述
请添加图片描述

3、填写模块名称,坐标信息,点击finish,创建完成
请添加图片描述

4、在Maven工程下,创建HelloWorld类
请添加图片描述

Maven项目的目录结构:

maven-project01
|— src (源代码目录和测试代码目录)
|— main (源代码目录)
|— java (源代码java文件目录)
|— resources (源代码配置文件目录)
|— test (测试代码目录)
|— java (测试代码java目录)
|— resources (测试代码配置文件目录)
|— target (编译、打包生成文件存放目录)

5、编写 HelloWorld,并运行

public class HelloWorld {
public static void main(String[] args) {
  System.out.println("Hello Maven ...");
}
}

1.3.2.2 POM配置详解

POM (Project Object Model) :指的是项目对象模型,用来描述当前的maven项目。

  • 使用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">
    <!-- POM模型版本 -->
    <modelVersion>4.0.0</modelVersion>

    <!-- 当前项目坐标 -->
    <groupId>com.yishooo</groupId>
    <artifactId>maven_project1</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- 打包方式 -->
    <packaging>jar</packaging>

</project>

pom文件详解:

  • :pom文件的根标签,表示当前maven项目
  • :声明项目描述遵循哪一个POM模型版本
    • 虽然模型本身的版本很少改变,但它仍然是必不可少的。目前POM模型版本是4.0.0
  • 坐标 :、、
    • 定位项目在本地仓库中的位置,由以上三个标签组成一个坐标
  • :maven项目的打包方式,通常设置为jar或war(默认值:jar)

3.2.3 Maven坐标详解

什么是坐标?

  • Maven中的坐标是资源的唯一标识 , 通过该坐标可以唯一定位资源位置
  • 使用坐标来定义项目或引入项目中需要的依赖

Maven坐标主要组成

  • groupId:定义当前Maven项目隶属组织名称(通常是域名反写,例如:com.itheima)
  • artifactId:定义当前Maven项目名称(通常是模块名称,例如 order-service、goods-service)
  • version:定义当前项目版本号
    请添加图片描述

注意:

  • 上面所说的资源可以是插件、依赖、当前项目。
  • 我们的项目如果被其他的项目依赖时,也是需要坐标来引入的。

1.3.3 导入Maven项目

  • 方式1:使用Maven面板,快速导入项目

打开IDEA,选择右侧Maven面板,点击 + 号,选中对应项目的pom.xml文件,双击即可
请添加图片描述

请添加图片描述

说明:如果没有Maven面板,选择 View => Appearance => Tool Window Bars
请添加图片描述

  • 方式2:使用idea导入模块项目

File => Project Structure => Modules => + => Import Module
请添加图片描述

找到要导入工程的pom.xml
请添加图片描述
请添加图片描述

1.4 依赖管理

1.4.1 依赖配置

依赖:指当前项目运行所需要的jar包。一个项目中可以引入多个依赖:

例如:在当前工程中,需要用到logback来记录日志,此时就可以在maven工程的pom.xml文件中,引入logback的依赖。具体步骤如下:

  1. 在pom.xml中编写标签

  2. 在标签中使用引入坐标

  3. 定义坐标的 groupId、artifactId、version

<dependencies>
    <!-- 第1个依赖 : logback -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.11</version>
    </dependency>
    <!-- 第2个依赖 : junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>
  1. 点击刷新按钮,引入最新加入的坐标
    • 刷新依赖:保证每一次引入新的依赖,或者修改现有的依赖配置,都可以加入最新的坐标
      请添加图片描述

注意事项:

  • 如果引入的依赖,在本地仓库中不存在,将会连接远程仓库 / 中央仓库,然后下载依赖(这个过程会比较耗时,耐心等待)
  • 如果不知道依赖的坐标信息,可以到mvn的中央仓库(https://mvnrepository.com/)中搜索

添加依赖的几种方式:

  1. 利用中央仓库搜索的依赖坐标
    请添加图片描述

  2. 利用IDEA工具搜索依赖
    请添加图片描述

  3. 熟练上手maven后,快速导入依赖
    请添加图片描述

1.4.2 依赖传递

1.4.2.1 依赖具有传递性

早期没有使用maven时,向项目中添加依赖的jar包,需要把所有的jar包都复制到项目工程下。如下图所示,需要logback-classic时,由于logback-classic又依赖了logback-core和slf4j,所以必须把这3个jar包全部复制到项目工程下
请添加图片描述

使用了maven,当项目中需要使用logback-classic时,只需要在pom.xml配置文件中,添加logback-classic的依赖坐标即可。
请添加图片描述

在pom.xml文件中只添加了logback-classic依赖,但由于maven的依赖具有传递性,所以会自动把所依赖的其他jar包也一起导入。

依赖传递可以分为:

  1. 直接依赖:在当前项目中通过依赖配置建立的依赖关系
  2. 间接依赖:被依赖的资源如果依赖其他资源,当前项目间接依赖其他资源
    请添加图片描述

比如以上图中:

  • projectA依赖了projectB。对于projectA 来说,projectB 就是直接依赖。
  • 而projectB依赖了projectC及其他jar包。 那么此时,在projectA中也会将projectC的依赖传递下来。对于projectA 来说,projectC就是间接依赖。
    请添加图片描述

1.4.2.2 排除依赖

依赖具有传递性。A依赖B,B依赖C,如果A不想将C依赖进来可以通过排除依赖来实现。

  • 排除依赖:指主动断开依赖的资源。(被排除的资源无需指定版本)
<dependency>
    <groupId>com.itheima</groupId>
    <artifactId>maven-projectB</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--排除依赖, 主动断开依赖的资源-->
    <exclusions>
    	<exclusion>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </exclusion>
    </exclusions>
</dependency>

1.4.3 依赖范围

在项目中导入依赖的jar包后,默认情况下,可以在任何地方使用。
请添加图片描述

如果希望限制依赖的使用范围,可以通过标签设置其作用范围。

作用范围:

  1. 主程序范围有效(main文件夹范围内)
  2. 测试程序范围有效(test文件夹范围内)
  3. 是否参与打包运行(package指令范围内)
    请添加图片描述

如上图所示,给junit依赖通过scope标签指定依赖的作用范围。 那么这个依赖就只能作用在测试环境,其他环境下不能使用。

scope标签的取值范围:

scope主程序测试程序打包(运行)范例
compile(默认)YYYlog4j
test-Y-junit
providedYY-servlet-api
runtime-YYjdbc驱动

1.4.4 生命周期

1.4.4.1 介绍

Maven的生命周期就是为了对所有的构建过程进行抽象和统一。 描述了一次项目构建,经历哪些阶段。

在Maven出现之前,项目构建的生命周期就已经存在,软件开发人员每天都在对项目进行清理,编译,测试及部署。虽然大家都在不停地做构建工作,但公司和公司间、项目和项目间,往往使用不同的方式做类似的工作。

Maven从大量项目和构建工具中学习和反思,然后总结了一套高度完美的,易扩展的项目构建生命周期。这个生命周期包含了项目的清理,初始化,编译,测试,打包,集成测试,验证,部署和站点生成等几乎所有构建步骤。

Maven对项目构建的生命周期划分为3套(相互独立):
请添加图片描述

  • clean:清理工作。

  • default:核心工作。如:编译、测试、打包、安装、部署等。

  • site:生成报告、发布站点等。

三套生命周期又包含哪些具体的阶段呢, 我们来看下面这幅图:
请添加图片描述

主要关注以下几个即可:

• clean:移除上一次构建生成的文件

• compile:编译项目源代码

• test:使用合适的单元测试框架运行测试(junit)

• package:将编译后的文件打包,如:jar、war等

• install:安装项目到本地仓库

IDEA工具为了方便程序员使用maven生命周期,在右侧的maven工具栏中,已给出快速访问通道
请添加图片描述

生命周期的顺序是:clean --> validate --> compile --> test --> package --> verify --> install --> site --> deploy 。主要关注:clean --> compile --> test --> package --> install

说明:在同一套生命周期中,我们在执行后面的生命周期时,前面的生命周期都会执行。

思考:当运行package生命周期时,clean、compile生命周期会不会运行?

​ clean不会运行,compile会运行。 因为compile与package属于同一套生命周期,而clean与package不属于同一套生命周期。

1.4.4.2 执行

在日常开发中,当我们要执行指定的生命周期时,有两种执行方式:

  1. 在idea工具右侧的maven工具栏中,选择对应的生命周期,双击执行
  2. 在DOS命令行中,通过maven命令执行

方式一:在idea中执行生命周期

  • 选择对应的生命周期,双击执行

方式二:在命令行中执行生命周期

  1. 进入到DOS命令行
  2. 在maven项目路径下执行 mvn clean(complile、test、package、install)

1.5 附录

1.5.1 更新依赖索引

有时候给idea配置完maven仓库信息后,在idea中依然搜索不到仓库中的jar包。这是因为仓库中的jar包索引尚未更新到idea中。这个时候我们就需要更新idea中maven的索引了,具体做法如下:

打开设置----搜索maven----Repositories----选中本地仓库-----点击Update
请添加图片描述

1.5.2 清理maven仓库

初始情况下,本地仓库是没有任何jar包的,此时会从私服去下载(如果没有配置,就直接从中央仓库去下载),可能由于网络的原因,jar包下载不完全,这些不完整的jar包都是以lastUpdated结尾。此时,maven不会再重新下载,需要主动删除这些以lastUpdated结尾的文件,然后maven才会再次自动下载这些jar包。
请添加图片描述

如果本地仓库中有很多这样的以lastUpadted结尾的文件,可以定义一个批处理文件,在其中编写如下脚本来删除:

set REPOSITORY_PATH=E:\develop\apache-maven-3.6.1\mvn_repo
rem 正在搜索...

del /s /q %REPOSITORY_PATH%\*.lastUpdated

rem 搜索完毕
pause

操作步骤如下:

定义批处理文件del_lastUpdated.bat (直接创建一个文本文件复制上述代码手动修改路径,命名为del_lastUpdated,后缀名直接改为bat即可 )双击运行即可删除maven仓库中的残留文件。

2. Maven高级

Maven高级内容包括:

  • 分模块设计与开发
  • 继承与聚合
  • 私服

2.1 分模块设计与开发

2.1.1 介绍

所谓分模块设计,顾名思义指的就是在设计一个 Java 项目的时候,将一个 Java 项目拆分成多个模块进行开发。

1). 未分模块设计的问题
请添加图片描述

如果项目不分模块,也就意味着所有的业务代码是不是都写在这一个 Java 项目当中。随着这个项目的业务扩张,项目当中的业务功能可能会越来越多。

假如开发的是一个大型的电商项目,里面可能就包括了商品模块的功能、搜索模块的功能、购物车模块、订单模块、用户中心等等。这些所有的业务代码都在一个 Java 项目当中编写。

这个项目组至少几十号甚至几百号开发人员,这些开发人员全部操作这一个 Java 项目。此时就会发现项目管理和维护起来将会非常的困难。假如在项目当中,自己定义了一些通用的工具类以及通用的组件,而公司还有其他的项目组,其他项目组也想使用封装的这些组件和工具类,其实是非常不方便的。因为 Java 项目当中包含了当前项目的所有业务代码,所以就造成了这里面所封装的一些组件会难以复用。

总结起来,主要两点问题:不方便项目的维护和管理、项目中的通用组件难以复用。

2). 分模块设计

分模块设计在进行项目设计阶段,就可以将一个大的项目拆分成若干个模块,每一个模块都是独立的。
请添加图片描述

可以将商品的相关功能放在商品模块当中,搜索的相关业务功能我都封装在搜索模块当中,还有像购物车模块、订单模块。而为了组件的复用,也可以将项目当中的实体类、工具类以及定义的通用的组件都单独的抽取到一个模块当中。

如果当前这个模块,比如订单模块需要用到这些实体类以及工具类或者这些通用组件,此时直接在订单模块当中引入工具类的坐标就可以了。这样就将一个项目拆分成了若干个模块儿,这就是分模块儿设计。

分模块儿设计之后,在进行项目管理的时候,可以几个人一组,几个人来负责订单模块儿,另外几个人来负责购物车模块儿,这样更加便于项目的管理以及项目的后期维护。

而且分模块设计之后,如果需要用到另外一个模块的功能,直接依赖模块就可以了。比如商品模块、搜索模块、购物车订单模块都需要依赖于通用组件当中封装的一些工具类,只需要引入通用组件的坐标就可以了。

分模块设计就是将项目按照功能/结构拆分成若干个子模块,方便项目的管理维护、拓展,也方便模块键的相互调用、资源共享。

2.1.2 实践

2.1.2.1 分析

需求:将之前的springboot案例进行分模块设计。

可以看到之前项目当中,除了所开发的部门管理以及员工管理、登录认证等相关业务功能以外,也定义了一些实体类,也就是pojo包下存放的一些类,像分页结果的封装类PageBean、 统一响应结果Result,此外还定义了一些通用的工具类,像Jwts、阿里云OSS操作的工具类等等。

如果在当前公司的其他项目组当中,也想使用所封装的这些公共的组件,可以考虑如下两种方案:

  • 方案一:直接依赖当前项目 zs-web-management ,但是存在两大缺点:

    • 这个项目当中包含所有的业务功能代码,而想共享的资源,仅仅是pojo下的实体类,以及 utils 下的工具类。如果全部都依赖进来,项目在启动时将会把所有的类都加载进来,会影响性能
    • 如果直接把这个项目都依赖进来了,那也就意味着我们所有的业务代码都对外公开了,这个是非常不安全的。
  • 方案二:分模块设计

    • 将pojo包下的实体类,抽取到一个maven模块中 zs-pojo
    • 将utils包下的工具类,抽取到一个maven模块中 zs-utils
    • 其他的业务代码,放在zs-web-management这个模块中,在该模块中需要用到实体类pojo、工具类utils,直接引入对应的依赖即可。
      请添加图片描述

注意:分模块开发需要先针对模块功能进行设计,再进行编码。不会先将工程开发完毕,然后进行拆分。

​ PS:当前是为了演示分模块开发,所以是基于前面开发的案例项目进行拆分的,实际中都是分模块设计,然后再开发的。

2.1.2.2 实现

1. 创建maven模块 zs-pojo,存放实体类

A. 创建一个正常的Maven模块,模块名zs-pojo
请添加图片描述
请添加图片描述

B. 然后在zs-pojo中创建一个包 com.yishooo.pojo (和原来案例项目中的pojo包名一致)
请添加图片描述

C. 将原来案例项目 zs-web-management 中的pojo包下的实体类,复制到zs-pojo模块中
请添加图片描述

D. 在 tlias-pojo 模块的pom.xml文件中引入依赖

<dependencies>
 <dependency>
     <groupId>org.projectlombok</groupId>
     <artifactId>lombok</artifactId>
     <version>1.18.26</version>
 </dependency>
</dependencies>

E. 删除原有案例项目zs-web-management的pojo包【已经将该模块拆分出去了,直接删除不要犹豫】,然后在pom.xml中引入 zs-pojo的依赖

<dependency>
 <groupId>com.yishooo</groupId>
 <artifactId>zs-pojo</artifactId>
 <version>1.0-SNAPSHOT</version>
</dependency>

2. 创建Maven模块 zs-utils,存放相关工具类

A. 创建一个正常的Maven模块,模块名zs-utils
请添加图片描述
请添加图片描述

B. 然后在 zs-utils 中创建一个包 com.yishooo.utils (和原来案例项目中的utils包名一致)
请添加图片描述

C. 将原来案例项目 zs-web-management 中的utils包下的实体类,复制到zs-utils模块中
请添加图片描述

D. 在 zs-utils 模块的pom.xml文件中引入依赖

<dependencies>
 <!--JWT令牌-->
 <dependency>
     <groupId>io.jsonwebtoken</groupId>
     <artifactId>jjwt</artifactId>
     <version>0.9.1</version>
 </dependency>

 <!--阿里云OSS-->
 <dependency>
     <groupId>com.aliyun.oss</groupId>
     <artifactId>aliyun-sdk-oss</artifactId>
     <version>3.15.1</version>
 </dependency>
 <dependency>
     <groupId>javax.xml.bind</groupId>
     <artifactId>jaxb-api</artifactId>
     <version>2.3.1</version>
 </dependency>
 <dependency>
     <groupId>javax.activation</groupId>
     <artifactId>activation</artifactId>
     <version>1.1.1</version>
 </dependency>
 <!-- no more than 2.3.3-->
 <dependency>
     <groupId>org.glassfish.jaxb</groupId>
     <artifactId>jaxb-runtime</artifactId>
     <version>2.3.3</version>
 </dependency>

 <!--WEB开发-->
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
     <version>2.7.11</version>
 </dependency>

 <dependency>
     <groupId>org.projectlombok</groupId>
     <artifactId>lombok</artifactId>
     <version>1.18.26</version>
 </dependency>
</dependencies>

E. 删除原有案例项目zs-web-management的utils包【已经将该模块拆分出去了,直接删除不要犹豫】,然后在pom.xml中引入 zs-utils的依赖

<dependency>
 <groupId>com.yishooo</groupId>
 <artifactId>zs-utils</artifactId>
 <version>1.0-SNAPSHOT</version>
</dependency>

到此,模块的拆分就已经完成了,拆分出了 zs-pojo、zs-utils、zs-web-management ,如果其他项目中需要用到 pojo,或者 utils工具类,就可以直接引入依赖。

2.1.3 总结

  1. 什么是分模块设计:将项目按照功能拆分成若干个子模块

  2. 为什么要分模块设计:方便项目的管理维护、扩展,也方便模块间的相互调用,资源共享

  3. 注意事项:分模块设计需要先针对模块功能进行设计,再进行编码。不会先将工程开发完毕,然后进行拆分

2.2 继承与聚合

在案例项目分模块开发之后,可以看到zs-pojo、zs-utils、zs-web-management中都引入了一个依赖 lombok 的依赖。在三个模块中分别配置了一次。
请添加图片描述

如果是做一个大型的项目,这三个模块当中重复的依赖可能会很多很多。如果每一个 Maven 模块里面,都来单独的配置一次,功能虽然能实现,但是配置是比较繁琐的。可以使用 Maven 的继承用来解决这问题的。

2.2.1 继承

可以再创建一个父工程 zs-parent ,然后让上述的三个模块 zs-pojo、zs-utils、zs-web-management 都来继承这个父工程 。 然后再将各个模块中共有的依赖,都提取到父工程 zs-parent中进行配置,只要子工程继承了父工程,依赖它也会继承下来,这样就无需在各个子工程中进行配置了。
请添加图片描述

  • 概念:继承描述的是两个工程间的关系,与java中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承。

  • 作用:简化依赖配置、统一管理依赖

  • 实现:

    <parent>
        <groupId>...</groupId>
        <artifactId>...</artifactId>
        <version>...</version>
        <relativePath>....</relativePath>
    </parent>
    

2.2.1.1 继承关系

2.2.1.1.1 思路分析

当前的项目 zs-web-management,还稍微有一点特殊,因为是一个springboot项目,而所有的springboot项目都有一个统一的父工程,就是spring-boot-starter-parent。 与java语言类似,Maven不支持多继承,一个maven项目只能继承一个父工程,如果继承了spring-boot-starter-parent,就没法继承我们自己定义的父工程 zs-parent了。

Java虽然不支持多继承,但是可以支持多重继承,比如:A 继承 B, B 继承C。 那在Maven中也是支持多重继承的,创建的三个模块,都继承zs-parent,而zs-parent 再继承 spring-boot-starter-parent。 具体结构如下:
请添加图片描述

2.2.1.1.2 实现

1). 创建maven模块 zs-parent ,该工程为父工程,设置打包方式pom(默认jar)。
请添加图片描述
请添加图片描述

工程结构如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SlQtAxmU-1684156298040)(E:\itcast\images\JavaWeb\day17\image15.png)]

父工程zs-parent的pom.xml文件配置如下:

<parent>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-parent</artifactId>
 <version>2.7.11</version>
 <relativePath/> <!-- lookup parent from repository -->
</parent>

<groupId>com.yishooo</groupId>
<artifactId>zs-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>

Maven打包方式:

  • jar:普通模块打包,springboot项目基本都是jar包(内嵌tomcat运行)
  • war:普通web程序打包,需要部署在外部的tomcat服务器中运行
  • pom:父工程或聚合工程,该模块不写代码,仅进行依赖管理

2). 在子工程的pom.xml文件中,配置继承关系。

<parent>
    <groupId>com.yishooo</groupId>
    <artifactId>zs-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../zs-parent/pom.xml</relativePath>
</parent>

<artifactId>zs-utils</artifactId>
<version>1.0-SNAPSHOT</version>

以 zs-utils 为例,指定了其父工程。其他的模块,都是相同的配置方式。

注意:

  • 在子工程中,配置了继承关系之后,坐标中的groupId是可以省略的,因为会自动继承父工程的 。
  • relativePath指定父工程的pom文件的相对位置(如果不指定,将从本地仓库/远程仓库查找该工程)。
    • …/ 代表的上一级目录

3). 在父工程中配置各个工程共有的依赖(子工程会自动继承父工程的依赖)。

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.26</version>
    </dependency>
</dependencies>

此时,已经将各个子工程中共有的依赖(lombok),都定义在了父工程中,子工程中的这一项依赖,就可以直接删除了。删除之后,会看到父工程中配置的依赖 lombok,子工程直接继承下来了。
请添加图片描述

工程结构说明:

  • 当前的项目结构为:
    请添加图片描述

因为是项目开发完毕之后,基于现有项目拆分的各个模块,zs-web-management已经存在了,然后再创建各个模块与父工程,所以父工程与模块之间是平级的。

  • 而实际项目中,可能还会见到下面的工程结构:
    请添加图片描述

而在真实的企业开发中,都是先设计好模块之后,再开始创建模块,开发项目。 先创建父工程 zs-parent,然后将创建的各个子模块,都放在父工程parent下面。 这样层级结构会更加清晰一些。

PS:上面两种工程结构,都是可以正常使用的,没有一点问题。 只不过,第二种结构,看起来,父子工程结构更加清晰、更加直观。

2.2.1.2 版本锁定

2.2.1.2.1 场景

如果项目中各个模块中都公共的这部分依赖,可以直接定义在父工程中,从而简化子工程的配置。 然而在项目开发中,还有一部分依赖,并不是各个模块都共有的,可能只是其中的一小部分模块中使用到了这个依赖。

比如:在zs-web-management、zs-web-system、zs-web-report这三个子工程中,都使用到了jwt的依赖。 但是 zs-pojo、zs-utils中并不需要这个依赖,那此时,这个依赖,不会直接配置在父工程 tlias-parent中,而是哪个模块需要,就在哪个模块中配置。

而由于是一个项目中的多个模块,多个模块中,要使用的同一个依赖的版本要一致,这样便于项目依赖的统一管理。比如:这个jwt依赖,都使用的是 0.9.1 这个版本。
请添加图片描述

假如项目要升级,要使用到jwt最新版本 0.9.2 中的一个新功能,操作步骤如下:

  • 第一步:去找当前项目中所有的模块的pom.xml配置文件,看哪些模块用到了jwt的依赖。

  • 第二步:找到这个依赖之后,将其版本version,更换为 0.9.2。

问题:如果项目拆分的模块比较多,每一次更换版本,都得找到这个项目中的每一个模块,一个一个的更改。 很容易就会出现,遗漏掉一个模块,忘记更换版本的情况。可以使用Maven的版本锁定功能解决此问题。

2.2.1.2.2 介绍

在maven中,可以在父工程的pom文件中通过 <dependencyManagement> 来统一管理依赖版本。

父工程:

<!--统一管理依赖版本-->
<dependencyManagement>
    <dependencies>
        <!--JWT令牌-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
    </dependencies>
</dependencyManagement>

子工程:

<dependencies>
    <!--JWT令牌-->
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
    </dependency>
</dependencies>

注意:

  • 在父工程中所配置的 <dependencyManagement> 只能统一管理依赖版本,并不会将这个依赖直接引入进来。 这点和 <dependencies> 是不同的。
  • 子工程要使用这个依赖,还是需要引入的,只是此时就无需指定 <version> 版本号了,父工程统一管理。变更依赖版本,只需在父工程中统一变更。
2.2.1.2.3 实现

接下来将zs-utils模块中单独配置的依赖,将其版本统一交给 zs-parent 进行统一管理。

具体步骤如下:

1). zs-parent 中的配置

<!--统一管理依赖版本-->
<dependencyManagement>
    <dependencies>
        <!--JWT令牌-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

        <!--阿里云OSS-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.15.1</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>
        <!-- no more than 2.3.3-->
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.3</version>
        </dependency>
    </dependencies>
</dependencyManagement>

2). zs-utils中的pom.xml配置

如果依赖的版本已经在父工程进行了统一管理,所以在子工程中就无需再配置依赖的版本了。

<dependencies>
    <!--JWT令牌-->
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
    </dependency>

    <!--阿里云OSS-->
    <dependency>
        <groupId>com.aliyun.oss</groupId>
        <artifactId>aliyun-sdk-oss</artifactId>
    </dependency>
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
    </dependency>
    <dependency>
        <groupId>javax.activation</groupId>
        <artifactId>activation</artifactId>
    </dependency>
    <!-- no more than 2.3.3-->
    <dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>jaxb-runtime</artifactId>
    </dependency>

    <!--WEB开发-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

之所以在springboot项目中很多时候,引入依赖坐标,都不需要指定依赖的版本 <version> ,是因为在父工程 spring-boot-starter-parent中已经通过 <dependencyManagement>对依赖的版本进行了统一的管理维护。

2.2.1.2.4 属性配置

可以通过自定义属性及属性引用的形式,在父工程中将依赖的版本号进行集中管理维护。 具体语法为:

1). 自定义属性

<properties>
	<lombok.version>1.18.26</lombok.version>
</properties>

2). 引用属性

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>${lombok.version}</version>
</dependency>

接下来,我们就可以在父工程中,将所有的版本号,都集中管理维护起来。

<properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>

    <lombok.version>1.18.26</lombok.version>
    <jjwt.version>0.9.1</jjwt.version>
    <aliyun.oss.version>3.15.1</aliyun.oss.version>
    <jaxb.version>2.3.1</jaxb.version>
    <activation.version>1.1.1</activation.version>
    <jaxb.runtime.version>2.3.3</jaxb.runtime.version>
</properties>


<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.version}</version>
    </dependency>
</dependencies>

<!--统一管理依赖版本-->
<dependencyManagement>
    <dependencies>
        <!--JWT令牌-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>${jjwt.version}</version>
        </dependency>

        <!--阿里云OSS-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>${aliyun.oss.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>${jaxb.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>${activation.version}</version>
        </dependency>
        <!-- no more than 2.3.3-->
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>${jaxb.runtime.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

版本集中管理之后,要想修改依赖的版本,就只需要在父工程中自定义属性的位置,修改对应的属性值即可。

面试题:<dependencyManagement><dependencies> 的区别是什么?

  • <dependencies> 是直接依赖,在父工程配置了依赖,子工程会直接继承下来。
  • <dependencyManagement> 是统一管理依赖版本,不会直接依赖,还需要在子工程中引入所需依赖(无需指定版本)

2.2.2 聚合

分模块设计与开发之后,项目被拆分为多个模块,而模块之间的关系,可能错综复杂。 就比如当前的案例项目,结构如下(相对还是比较简单的):
请添加图片描述

此时,zs-web-management 模块的父工程是 zs-parent,该模块又依赖了zs-pojo、zs-utils模块。 要想将 zs-web-management 模块打包,是比较繁琐的。因为在进行项目打包时,maven会从本地仓库中来查找zs-parent父工程,以及它所依赖的模块zs-pojo、zs-utils,而本地仓库目前是没有这几个依赖的。

所以,在打包zs-web-management 模块前,需要将 zs-parent、zs-pojo、zs-utils分别执行install生命周期安装到maven的本地仓库,然后再针对于 zs-web-management 模块执行package进行打包操作。

如果开发一个大型项目,拆分的模块很多,模块之间的依赖关系错综复杂,那此时要进行项目的打包、安装操作,是非常繁琐的。 但是maven的聚合就可以解决这个问题的,通过maven的聚合就可以轻松实现项目的一键构建(清理、编译、测试、打包、安装等)。

2.2.2.1 介绍

请添加图片描述

  • **聚合:**将多个模块组织成一个整体,同时进行项目的构建。
  • **聚合工程:**一个不具有业务功能的“空”工程(有且仅有一个pom文件) 【PS:一般来说,继承关系中的父工程与聚合关系中的聚合工程是同一个】
  • **作用:**快速构建项目(无需根据依赖关系手动构建,直接在聚合工程上构建即可)

2.2.2.2 实现

在maven中,可以在聚合工程中通过 <moudules> 设置当前聚合工程所包含的子模块的名称。可以在 zs-parent中,添加如下配置,来指定当前聚合工程,需要聚合的模块:

<!--聚合其他模块-->
<modules>
    <module>../zs-pojo</module>
    <module>../zs-utils</module>
    <module>../zs-web-management</module>
</modules>

此时要进行编译、打包、安装操作,就无需在每一个模块上操作了。只需要在聚合工程上,统一进行操作就可以了。

**测试:**执行在聚合工程 zs-parent 中执行 package 打包指令
请添加图片描述

那 zs-parent 中所聚合的其他模块全部都会执行 package 指令,这就是通过聚合实现项目的一键构建(一键清理clean、一键编译compile、一键测试test、一键打包package、一键安装install等)。

2.2.3 继承与聚合对比

  • 作用

    • 聚合用于快速构建项目

    • 继承用于简化依赖配置、统一管理依赖

  • 相同点:

    • 聚合与继承的pom.xml文件打包方式均为pom,通常将两种关系制作到同一个pom文件中

    • 聚合与继承均属于设计型模块,并无实际的模块内容

  • 不同点:

    • 聚合是在聚合工程中配置关系,聚合可以感知到参与聚合的模块有哪些

    • 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己

2.3 私服

2.3.1 场景

在介绍什么是私服之前,先来分析一下同一个公司,两个项目组之间如何基于私服进行资源的共享。

假设现在有两个团队,A 和 B。 A 开发了一个模块 zs-utils,模块开发完毕之后,将模块打成jar包,并安装到了A的本地仓库。
请添加图片描述

该公司的B团队开发项目时,要想使用 zs-utils 中提供的工具类,对于maven项目来说,是不是在pom.xml文件中引入 zs-utils的坐标就可以了呢?
请添加图片描述

当B团队在maven项目的pom.xml配置文件中引入了依赖的坐标之后,maven是如何查找这个依赖的? 查找顺序为:

1). 本地仓库:本地仓库中是没有这个依赖jar包的。

2). 远程中央仓库:由于该模块时自己公司开发的,远程仓库中也没有这个依赖。

因为目前zs-utils这个依赖,还在A的本地仓库中的。 B电脑上的maven项目,是不可能找得到A电脑上maven本地仓库的jar包的。 那此时,大家可能会有一个想法:因为A和B都会连接中央仓库,可以将A本地仓库的jar包,直接上传到中央仓库,然后B从中央仓库中下载zs-utils这个依赖。
请添加图片描述

这个想法很美好,但是现实很残酷。这个方案是行不通的,因为中央仓库全球只有一个,不是什么人都可以往中央仓库中来上传jar包的,是没有权限操作的。

此时maven的私服就起到关键作用了,私服其实就是架设在公司局域网内部的一台服务器,就是一种特殊的远程仓库。

有了私服之后,各个团队就可以直接来连接私服了。 A 连接上私服之后,他就可以把jar包直接上传到私服当中。公司自己内部搭建的服务器,有权限操作,把jar包上传到私服之后,让 B 团队的所有开发人员也连接同一台私服。连接上这一台私服之后,就会根据坐标的信息,直接从私服当中将对应的jar包下载到自己的本地仓库,这样就可以使用到依赖当中所提供的一些工具类了。达到通过私服来完成资源的共享的目的。
请添加图片描述

在项目中需要使用其他第三方提供的依赖,如果本地仓库没有,会自动连接私服下载,如果私服没有,私服此时会自动连接中央仓库,去中央仓库中下载依赖,然后将下载的依赖存储在私服仓库及本地仓库中。

2.3.2 介绍

  • **私服:**是一种特殊的远程仓库,它是架设在局域网内的仓库服务,用来代理位于外部的中央仓库,用于解决团队内部的资源共享与资源同步问题。
  • 依赖查找顺序:
    • 本地仓库
    • 私服仓库
    • 中央仓库
  • **注意事项:**私服在企业项目开发中,一个项目/公司,只需要一台即可。
    请添加图片描述

2.3.3 资源上传与下载

2.3.3.1 步骤分析

请添加图片描述

资源上传与下载,需要做三步配置,执行一条指令。

第一步配置:在maven的配置文件中配置访问私服的用户名、密码。

第二步配置:在maven的配置文件中配置连接私服的地址(url地址)。

第三步配置:在项目的pom.xml文件中配置上传资源的位置(url地址)。

配置好了上述三步之后,要上传资源到私服仓库,就执行执行maven生命周期:deploy。

私服仓库说明:

  • RELEASE:存储自己开发的RELEASE发布版本的资源。
  • SNAPSHOT:存储自己开发的SNAPSHOT发布版本的资源。
  • Central:存储的是从中央仓库下载下来的依赖。

项目版本说明:

  • RELEASE(发布版本):功能趋于稳定、当前更新停止,可以用于发行的版本,存储在私服中的RELEASE仓库中。
  • SNAPSHOT(快照版本):功能不稳定、尚处于开发中的版本,即快照版本,存储在私服的SNAPSHOT仓库中。

2.3.3.2 具体操作

为了模拟企业开发,以本地作为一台服务器(127.0.0.1),私服已经搭建好了,可以访问私服测试:http://localhost:8081
请添加图片描述

私服准备好了之后,要做如下几步配置:

1.设置私服的访问用户名/密码(在自己maven安装目录下的conf/settings.xml中的servers中配置)

<server>
    <id>maven-releases</id>
    <username>admin</username>
    <password>admin</password>
</server>
    
<server>
    <id>maven-snapshots</id>
    <username>admin</username>
    <password>admin</password>
</server>

2.设置私服依赖下载的仓库组地址(在自己maven安装目录下的conf/settings.xml中的mirrors、profiles中配置)

<mirror>
    <id>maven-public</id>
    <mirrorOf>*</mirrorOf>
    <url>http://localhost:8081/repository/maven-public/</url>
</mirror>
<profile>
    <id>allow-snapshots</id>
        <activation>
        	<activeByDefault>true</activeByDefault>
        </activation>
    <repositories>
        <repository>
            <id>maven-public</id>
            <url>http://localhost:8081/repository/maven-public/</url>
            <releases>
            	<enabled>true</enabled>
            </releases>
            <snapshots>
            	<enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
</profile>

3.IDEA的maven工程的pom文件中配置上传(发布)地址(直接在zs-parent中配置发布地址)

<distributionManagement>
    <!-- release版本的发布地址 -->
    <repository>
        <id>maven-releases</id>
        <url>http://localhost:8081/repository/maven-releases/</url>
    </repository>

    <!-- snapshot版本的发布地址 -->
    <snapshotRepository>
        <id>maven-snapshots</id>
        <url>http://localhost:8081/repository/maven-snapshots/</url>
    </snapshotRepository>
</distributionManagement>

配置完成之后,就可以在zs-parent中执行deploy生命周期,将项目发布到私服仓库中。
请添加图片描述

通过日志,我们可以看到,这几个模块打的jar包确实已经上传到了私服仓库中(由于当前项目是SNAPSHOT版本,所以jar包是上传到了snapshot仓库中)。

打开私服查看如下:
请添加图片描述

项目中的这几个模块,在私服中都有了。其他项目组的开发人员在项目中,就可以直接通过依赖的坐标,就可以完成引入对应的依赖,此时本地仓库没有,就会自动从私服仓库中下载。

请添加图片描述

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

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

相关文章

代码随想录训练营Day37| 738.单调递增的数字 968.监控二叉树 总结

目录 学习目标 学习内容 738.单调递增的数字 968.监控二叉树 总结 学习目标 738.单调递增的数字 968.监控二叉树 总结 学习内容 738.单调递增的数字 738. 单调递增的数字 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/monotone-increasing-di…

【云计算与虚拟化】第二章 实验二 Vmware Workstation 15的使用

实验二 Vmware Workstation 15的使用 在上一实验的基础上&#xff0c;将两台虚拟机调节到在桥接模式下&#xff0c;配置相应的网络参数&#xff0c;实现虚拟机1和2能相互通信&#xff0c;虚拟机1和2能够ping通外网&#xff0c;虚拟机1和2能ping通物理机。 &#xff08;截取…

GE SR469-P5-HI-A20 带有5A相CT次级线圈的标准装置

SR469-P5-HI-A20提供四路4-20 mA模拟输出。该装置已通过CE认证。这是一个带有5A相CT次级线圈的标准装置。该装置的控制电源额定为90-300伏直流电&#xff0c;70-265伏交流电&#xff0c;48-62赫兹。 制造商美国通用电气公司&#xff0c;通用工业系统电压供应交流电:48-62赫兹时…

【云计算与虚拟化】第四章 实验一 在Windows 系统部署vCenter Server

实验一 在Windows 系统部署vCenter Server 1.部署两台ESXi6.0 虚拟主机&#xff0c;其余参数可以参考实验IP拓扑 2.在Windows Server 2012 R2中部署Storge服务器,该服务器名字为&#xff1a;姓名的拼音的首字母1&#xff0c;且要实现以下三个功能&#xff1a; (1)AD域控制…

【5.15】一、软件测试基础—软件概述

目录 1.1 软件概述 1.1.1 软件生命周期 1.1.2 软件开发模型 1.1.3 软件质量概述 1.1 软件概述 软件是相对于硬件而言的&#xff0c;它是一系列按照特定顺序组织的计算机数据和指令的集合。 软件的生命周期&#xff1a;软件从“出生” 到 “消亡” 的过程。 1.1.1 软件生…

超详细!Xmind的学习

哈喽&#xff0c;大家好。最近有小伙伴问使用xmind思维导图怎么快速上手&#xff0c;今天便给各位小伙伴出了这一期快速上手教程。思维导图的上手其实都是很简单的&#xff0c;只要知道基本功能的使用&#xff0c;基本上半天就能学会&#xff0c;一天就能熟练。 一、学习准备 …

【SpringBoot整合JWT】

目录 一、什么是JWT 二、JWT能做什么 三、为什么是JWT 1、基于传统的Session认证 2、基于JWT认证 四、JWT的结构是什么 五、JWT的第一个程序 六、封装JWT工具类 七、整合SpringBoot使用 一、什么是JWT JSON Web Token (JWT) is an open standard ([RFC 7519](http…

chatgpt赋能Python-python2转换为python3

Python 2到Python 3的转换和优化 在过去的几年中&#xff0c;Python 3已经成为了最流行的Python版本。因此&#xff0c;Python 2用户开始转向Python 3&#xff0c;以提高性能、安全性和可靠性。本文将讨论Python 2到Python 3的转换以及一些实用的优化技巧。 为什么要转向Pyth…

chatgpt赋能Python-python3_0列表排序方法

Python 3.0列表排序方法介绍 Python是一门广泛应用、适应性强的编程语言&#xff0c;而Python由于其简洁明了、易于学习、适合初学者的特点&#xff0c;是许多人最喜欢的编程语言之一。 Python 3.0列表排序方法是许多Python爱好者和开发者常用的功能之一。Python 3.0列表排序…

计算机网络 IP 1.1 IP基础知识

1. IP基本认识 网络层是实现主机与主机之间的通信。也叫点对点通信。 网络层(IP)和数据链路层&#xff08;网络接口层&#xff09;(MAC)有什么区别&#xff1f; IP是负责在没有直连的两个网络之间进行通信&#xff0c;MAC负责两个直连设备之间的通信。 只有两者一块使用&…

EasyRecovery Photo16数据恢复软件免费版下载或使用方法及安装激活教程

EasyRecovery Photo16数据恢复软件免费版下载是一款支持Mac/Wind平台进行恢复图片的专业工具&#xff0c;尤其是各种流行单反相机RAW格式文件&#xff0c;以及超大型视频文件等&#xff0c;摄影爱好者使用。EasyRecovery是一款非常专业的硬盘数据恢复工具&#xff0c;可以帮你恢…

windows搭建pyspark环境详细教程

一.安装jdk及配置环境变量: 下载地址&#xff1a; https://www.oracle.com/java/technologies/downloads/#java8-windows 安装步骤&#xff1a; 下载后点击安装&#xff0c;中途可以自定义安装路径&#xff0c;最后查看安装路径&#xff1a; 开始配置系统环境变量&#xff1a…

IS215UCVEM08B US2000型处理器板

IS215UCVEM08B US2000型处理器板通用电气标志VI卡 这IS215UCVEM08B是一种印刷电路板&#xff0c;是通用电气公司制造的Mark VI Speedtronic涡轮系列的一部分。这IS215UCVEM08B有一个小的圆形锂电池。这IS215UCVEM08B有几个链接点。电路板右手边有三个娇小的小鹿点。电路板背面…

【LLM系列之GPT】GPT(Generative Pre-trained Transformer)生成式预训练模型

GPT模型简介 GPT&#xff08;Generative Pre-trained Transformer&#xff09;是由OpenAI公司开发的一系列自然语言处理模型&#xff0c;采用多层Transformer结构来预测下一个单词的概率分布&#xff0c;通过在大型文本语料库中学习到的语言模式来生成自然语言文本。GPT系列模…

【STM32G431RBTx】备战蓝桥杯嵌入式→决赛试题→第九届

文章目录 前言一、题目![请添加图片描述](https://img-blog.csdnimg.cn/ccdd07679c9b4d86b6faad3554637eba.png)二、模块初始化三、代码实现interrupt.h:interrupt.c:main.h:main.c: 四、完成效果五、总结 前言 无 一、题目 二、模块初始化 1.LCD这里不用配置&#xff0c;直…

[FlareOn6]Overlong 题解

这个题是不需要逆向加密函数就可以得到flag的&#xff0c;可以直接动态调试得到flag比较快一点 这个冒号后面有东西没有输出 查看主函数的汇编 push 1Ch push offset unk_402008 是调用下面这个函数前的参数传递 call sub_401160 观察这个函数&#xff0c;push …

研发工程师玩转Kubernetes——构建、推送自定义镜像

这几节我们都是使用microk8s学习kubernetes&#xff0c;于是镜像库我们也是使用它的插件——registry。 开启镜像库插件 microk8s enable registry模拟开发环境 我们使用Python作为开发语言来进行本系列的演练。 安装Python sudo apt install python3.11安装Pip3 pip3用于…

chatgpt赋能Python-python3_5怎么安装

Python3.5的安装方法 对于想要学习Python编程的新手来说&#xff0c;Python的版本安装是必须要掌握的技能。在本文中&#xff0c;我们将介绍如何安装Python3.5版本。 介绍 Python是一门简单易学的高级编程语言&#xff0c;其代码易于阅读&#xff0c;容易维护。Python有很多…

JAVA—实验3 继承与多态

一、实验目的 1.掌握类的继承机制 2.掌握抽象类的定义方法 2.熟悉类中成员变量和方法的访问控制 3.熟悉成员方法或构造方法的多态性 二、实验内容 1. Circle类及其子类 【问题描述】 实现类Circle&#xff0c;半径为整型私有数据成员 1&#xff09;构造方法&#xff1a;参数为…

留学文书可以彻底被AI取代吗?留学顾问是否会被AI逼到墙角?

近日&#xff0c;ChatGPT再次“进化”&#xff0c;其最新版本ChatGPT-4又掀高潮。其生产者OpenAI 称&#xff0c;“ChatGPT-4是最先进的系统&#xff0c;能生产更安全和更有用的回复。”和上一代相比&#xff0c;GPT-4拥有了更广的知识面和更强的解决问题能力&#xff0c;在创意…