2. Maven 继承与聚合

目录

2.

2.1 继承

2.2继承关系

2.2.1 思路分析

2.2.2 实现

2.1.2 版本锁定

2.1.2.1 场景

2.1.2.2 介绍

2.1.2.3 实现

2.1.2.4 属性配置

2.2 聚合

2.2.1 介绍

2.2.2 实现

2.3 继承与聚合对比



maven1:分模块设计开发

2.

在项目分模块开发之后啊,我们会看到tlias-pojo、tlias-utils、tlias-web-management中都引入了一个依赖 lombok 的依赖。我们在三个模块中分别配置了一次。

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

而接下来主要就是 Maven 的继承用来解决这问题。

2.1 继承

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

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

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

  • 实现:

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

    继承以及继承的作用以及在 maven 当中如何来实现这层继承关系。接下来我们就来创建这样一个 parent 父工程,我们就可以将各个子工程当中共有的这部分依赖统一的定义在父工程 parent 当中,从而来简化子工程的依赖配置。

2.2继承关系

2.2.1 思路分析

Java虽然不支持多继承,但是可以支持多重继承,比如:A 继承 B, B 继承C。 那在Maven中也是支持多重继承的,所以呢,我们就可以让 我们自己创建的三个模块,都继承tlias-parent,而tlias-parent 再继承 spring-boot-starter-parent,就可以了。 具体结构如下:

2.2.2 实现

1). 创建maven模块 tlias-parent ,该工程为父工程,设置打包方式pom(默认jar)。

 

工程结构如下:  

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

<groupId>com.itheima</groupId>
<artifactId>tlias-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.itheima</groupId>
    <artifactId>tlias-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../tlias-parent/pom.xml</relativePath>
</parent>

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

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

注意:

  • 在子工程中,配置了继承关系之后,坐标中的groupId是可以省略的,因为会自动继承父工程的 。

  • relativePath指定父工程的pom文件的相对位置(如果不指定,将从本地仓库/远程仓库查找该工程)。

    • ../ 代表的上一级目录

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

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

```xml
<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.24</version>
    </dependency>
</dependencies>
```

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

工程结构说明:

结构可以有两种  理解就行

  • 我们当前的项目结构为:

 

  • 创建的各个模块与父工程,所以父工程与模块之间是平级的。

  • 而其余项目中,可能还会见到下面的工程结构:

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

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

2.1.2 版本锁定
2.1.2.1 场景

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

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

而由于是一个项目中的多个模块,那多个模块中,我们要使用的同一个依赖的版本要一致,这样便于项目依赖的统一管理。比如:这个jwt依赖,我们都使用的是 0.9.1 这个版本。

那假如说,我们项目要升级,要使用到jwt最新版本 0.9.2 中的一个新功能,那此时需要将依赖的版本升级到0.9.2,那此时该怎么做呢 ?

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

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

问题:如果项目拆分的模块比较多,每一次更换版本,我们都得找到这个项目中的每一个模块,一个一个的更改。 很容易就会出现,遗漏掉一个模块,忘记更换版本的情况。

那我们又该如何来解决这个问题,如何来统一管理各个依赖的版本呢?

答案:Maven的版本锁定功能。

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.1.2.3 实现

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

具体步骤如下:

1). tlias-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). tlias-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.1.2.4 属性配置

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

1). 自定义属性

<properties>
    <lombok.version>1.18.24</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.24</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 聚合

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

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

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

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

2.2.1 介绍

  • 聚合:将多个模块组织成一个整体,同时进行项目的构建。

  • 聚合工程:一个不具有业务功能的“空”工程(有且仅有一个pom文件) 【PS:一般来说,继承关系中的父工程与聚合关系中的聚合工程是同一个】

  • 作用:快速构建项目(无需根据依赖关系手动构建,直接在聚合工程上构建即可)

2.2.2 实现

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

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

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

测试:执行在聚合工程 tlias-parent 中执行 package 打包指令

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

2.3 继承与聚合对比

  • 作用

    • 聚合用于快速构建项目

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

  • 相同点:

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

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

  • 不同点:

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

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

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

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

相关文章

【Qt学习笔记】Qt Creator环境下 信号与槽 详解(自定义信号槽、断连、lambda表达式等)

文章目录 1. 信号槽概念1.1 信号的本质1.2 槽的本质1.3 标准信号槽1.4 信号槽 实例 2. 自定义信号槽2.1 自定义槽函数2.2 自定义信号2.3 带参 信号槽 3. 信号槽的意义 与 作用4. 信号槽断连 &#xff08;了解&#xff09;5. lamda表达式的使用5.1 基本用法5.2 捕获局部变量5.3 …

代码随想录算法训练营DAY16 | 二叉树 (3)

一、LeetCode 104 二叉树的最大深度 题目链接&#xff1a;104.二叉树的最大深度https://leetcode.cn/problems/maximum-depth-of-binary-tree/ 思路&#xff1a;采用后序遍历递归求解。 class Solution {int ans 0;public int maxDepth(TreeNode root) {if(root null){retur…

阿里云学生服务器完成验证领取300元无门槛代金券和优惠权益

阿里云高校计划「云工开物」学生和教师均可参与&#xff0c;完成学生认证和教师验证后学生可以免费领取300元无门槛代金券和3折优惠折扣&#xff0c;适用于云服务器等全量公共云产品&#xff0c;订单原价金额封顶5000元/年&#xff0c;阿里云百科aliyunbaike.com分享阿里云高校…

2024等保贯穿总结

严重不符合项&#xff1a; 离职人员不能在报告上签字&#xff01;&#xff01;&#xff01;因为人员离职导致测评人员不够的&#xff08;会开观察项&#xff09; 业务受理人员&#xff1a;管合同的人员、签合同的人员、市场部和人员有关的人员都要写进来 签字的人员一定要有相…

rust语言tokio库底层原理解析

目录 1 rust版本及tokio版本说明1 tokio简介2 tokio::main2.1 tokio::main使用多线程模式2.2 tokio::main使用单线程模式 3 builder.build()函数3.1 build_threaded_runtime()函数新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图…

springboot-web服务迁移Kubernetes

1、搞定基础镜像 docker pull openjdk:8-jre-alpine docker tag openjdk:8-jre-alpine 10.204.82.15/kubernetes/openjdk:8-jre-alpine docker push 10.204.82.15/kubernetes/openjdk:8-jre-alpine 2、springboot-web应用服务打包 3、编写Dockerfile构建镜像 FROM 10.204.82.…

STM32——中断

1 什么是中断 中断&#xff1a;打断CPU执行正常的程序&#xff0c;转而处理紧急程序&#xff0c;然后返回原暂停的程序继续运行&#xff1b; 对于单片机来说&#xff0c;中断是指CPU正在处理某个事件A&#xff0c;发生了另一件事件B&#xff0c;请求CPU迅速去处理&#xff08;…

使用npm包js-web-screen-shot做网页截图,可以对截图加文字,箭头等等,类似于微信截图

<template><div class"m-feedback-wrap" :style"{ top: ${feedbackHeight}px }"><div class"m-feedback-icon-wrap"><el-tooltipclass"item"effect"dark"content"内容"placement"left-…

【数据分享】1929-2023年全球站点的逐年平均风速(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2023年全球气象站…

文心一言 VS 讯飞星火 VS chatgpt (196)-- 算法导论14.3 4题

四、用go语言&#xff0c;给定一棵区间树 T 和一个区间 i &#xff0c;请描述如何在 O(min(n&#xff0c;klgn)) 时间内列出 T 中所有与 i 重叠的区间&#xff0c;其中 k 为输出的区间数。(提示:一种简单的方法是做若干次查询&#xff0c;并且在这些查询操作中修改树&#xff0…

springboot164党员教育和管理系统

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

初识NodeJS

本文主要基于极客时间《Nodejs开发实战》课程。 本篇&#xff08;一&#xff09;为课程的第二篇——技术预研篇。 什么是Nodejs? 来源官网&#xff1a; Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型&#x…

【网络技术】【Kali Linux】Nmap嗅探(二)多设备扫描

上期实验博文&#xff1a;&#xff08;一&#xff09;简单扫描 一、实验环境 本次实验进行Nmap多设备扫描&#xff0c;实验使用 Kali Linux 虚拟机&#xff08;扫描端&#xff09;、Ubuntu 22.04虚拟机&#xff08;被扫描端1&#xff09;、Ubuntu 18.04虚拟机&#xff08;被扫…

金融信贷风控业务详解

前言 Hi&#xff0c;大家好。今天我要根据以往的工作经验做一个全新的业务——金融风控、信贷风控等风控场景。带大家以全新的角度了解风控&#xff0c;包括风控信贷业务讲解、风控决策树、风控决策流、特征工程、三方数据对比和风控系统搭建等一系列知识。 早期的信贷风控做…

代码随想录算法训练营第30天| 51. N皇后、总结

51. N皇后 完成 思路&#xff1a; 如何用回溯法搜索二维棋盘是这道题目和之前不一样的地方&#xff0c;也是题目的难点。 在树形结构中&#xff0c;同层取同一行棋盘的不同列遍历。每递归一次就往下遍历一行。 代码 class Solution {List<List<String>> res n…

platform tree架构下i2c应用实例(HS3003)

目录 概述 1 探究platform tree下的i2c 1.1 platform tree下的i2c驱动 1.2 查看i2c总线下的设备 1.3 使用命令读写设备寄存器 2 认识HS3003 2.1 HS3003特性 2.2 HS3003寄存器 2.2.1 温湿度数据寄存器 2.2.2 参数寄存器 2.2.3 一个参数配置Demo 2.3 温湿度值转换 2.…

FANUC机器人外部远程启动的相关参数设置示例

FANUC机器人外部远程启动的相关参数设置示例 如下图所示,在MENU---设置---选择程序中,设置程序选择模式:RSR(这个根据自己实际使用的自动启动方式来决定,你用RSR选RSR,用PNS就选PNS), 自动运行开始方法:选择UOP,即RSR1-RSR8的启动信号分别对应UI9-UI16, 最后,点击…

一个 SpringBoot 项目能同时处理多少请求?

目录 1 问题分析 2 Demo 3 答案 4 怎么来的&#xff1f; 5 标准答案及影响参数一Tomcat配置 6 影响参数二 Web容器 7 影响参数三 Async 1 问题分析 一个 SpringBoot 项目能同时处理多少请求&#xff1f; 不知道你听到这个问题之后的第一反应是什么&#xff1f; 我大概…

从零开始手写mmo游戏从框架到爆炸(十)— 集成springboot-jpa与用户表

导航&#xff1a;从零开始手写mmo游戏从框架到爆炸&#xff08;零&#xff09;—— 导航-CSDN博客 集成springboot-jpa&#xff0c;不用mybatis框架一个是方便对接不同的数据源。第二个目前规划的游戏内容可能对数据库的依赖不是很大&#xff0c;jpa应该肯定能满足要求了…

redis之布隆过滤

目录 1、redis之布隆过滤 2、布隆过滤器原理 3、布隆过滤器使用步骤 初始化bitmap 添加占坑位 判断是否存在圜 1、redis之布隆过滤 布隆过滤&#xff1a;有一个初值都为0的bit数组和多个哈希函数构成&#xff0c;用来快速判断集合中是否存在某个元素。目的&#xff1a;减…