Maven聚合与继承

news/2024/11/9 16:45:14/

聚合

当我们一次想要构建多个项目时,而不是到每一个模块的目录下分别执行mvn命令。这个时候就需要使用到maven的聚合特性

在这里插入图片描述

  • 这里第一个特殊的地方是packaging,值设置为pom。我们正常开发的其他模块中都没有声明packaging,默认使用了默认值jar,但是对于聚合模块来说,其打包方式必须为pom,否则无法构建。

  • 元素 modules 是实现聚合的核心配置,用户可以通过在一个打包方式为pom的Maven项目中声明任意数量的module元素来实现模块的聚合,这里每一个module值都是一个当前pom的相对目录,因此一般来说模块所处的目录名称应当与其artifactId一致,也可以进行自定义名称更改对应的module配置就可以。

  • 一般来说,为了方便用户构建项目,通常将聚合模块放在项目目录的最底层,其他模块则作为聚合模块的子目录存在,这样当用户得到源码的时候第一眼发现的就是聚合模块的pom,不用从多个模块中去寻找聚合模块来构建整个项目。
    在这里插入图片描述

继承

当我们多个模块下存在很多相同的配置时,例如它们都有相同的groupId和version,有相同的spring-core,slf4j,junit依赖,还有相同的maven-compiler-plugin配置时。在mavne的世界中,也有类似的机制能让我们抽取出重复的配置,这就是pom的继承
在这里插入图片描述

  • 上图pom中使用parent声明父模块,parent下的子元素,groupId,artifactId和version指定了父模块的坐标,这三个元素是必须的,还有一个元素relativePath表示父模块pom相对路径。当项目构建时,Maven会首先根据relativePath检查父pom,如果找不到,再从本地仓库查找。relativePath默认值是<relativePath>../pom.xml</relativePath>,也就是说Maven默认父pom在上一层目录下。

  • 图中我们的pipeline 这个模块并没有声明groupId和verison,这并不代表我们这个模块中没有groupId和verison。实际上我们这个子模块隐式的从父模块中继承了这两个元素,消除了一些不必要的配置,如果遇到子模块需要使用和父模块不一样的groupId和verison,那么可以在子模块中显示声明

可继承的POM元素

  1. groupId:项目组ID,项目坐标的核心元素

  2. version:项目版本,项目坐标的核心元素

  3. description:项目的描述信息

  4. organization:项目的组织信息

  5. inceptionYear:项目的创始年份

  6. url:项目的URL地址

  7. developers:项目的开发者信息

  8. contributors:项目的贡献者信息

  9. distributionManagement:项目的部署配置

  10. issueManagement:项目的缺陷跟踪系统信息

  11. ciManagement:项目的持续集成系统信息

  12. scm:项目的版本控制系统信息

  13. mailingLists:项目的邮件列表信息

  14. properties:自定义的Maven属性

  15. dependencies:项目的依赖配置

  16. dependencyManagement:项目的依赖管理配置

  17. repositories:项目的仓库配置

  18. build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等

  19. reporting:包括项目的报告输出目录配置、报告插件配置等。

依赖管理

    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.3.2.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>2.3.2.RELEASE</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.12</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>com.zaxxer</groupId><artifactId>HikariCP</artifactId></dependency></dependencies>

maven的可继承元素列表包含了dependencies元素,这说明依赖是会被继承的,这时我们可以将一些共用依赖放到父模块中,子模块就可以移除这些依赖,简化配置。但同时也会产生其他问题,目前我们的子模块中都需要上述父模块中的依赖,假如将来项目中需要加入一个util模块,该模块只是需要提供一些工具,与springframework完全无关,难道也让它依赖sping相关依赖吗?这样显然是不合理的。为此 Maven 引入了 dependencyManagement 来对依赖进行管理。

dependencyManagement

    <!-- 该标签只用来控制版本,不能将依赖引入 --><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.3.2.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>2.3.2.RELEASE</version></dependency></dependencies></dependencyManagement>

Maven 可以通过 dependencyManagement 元素对依赖进行管理,它具有以下 2 大特性:

  • 在该元素下声明的依赖不会实际引入到模块中,只有在 dependencies 元素下同样声明了该依赖,才会引入到模块中。
  • 该元素能够约束 dependencies 下依赖的使用,即 dependencies 声明的依赖若未指定版本,则使用 dependencyManagement 中指定的版本,否则将覆盖 dependencyManagement 中的版本。
    在这里插入图片描述

更改pipeline 子模块对应的配置,我们在dependencies中只需要配置 groupId 和 artifactId,省去了 version 和 scope。之所以能够省略这些信息,是因为它们继承了父模块 Root 中 dependencyManagement 的配置,其完整的依赖声明已经包含在父模块的 POM 中,子模块只需要配置 groupId 和 artifactId 就能获得相应的依赖信息,从而引入正确的依赖。

优点:
  • 在父模块中使用dependencyManagement 声明依赖能够统一项目内依赖的版本,子模块无须声明版本,也就不会出现多个子模块使用同一依赖项版本不一致的情况,降低依赖冲突的几率。
  • dependencyManagement 声明的依赖不会被实际引入,子模块需要什么依赖就自己引入,增加了灵活性,避免引入一些不必要的依赖。

扩展

    <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version></parent>

在这里插入图片描述

在这里插入图片描述

单继承问题

现在有个问题,我现在想使用spring-boot-starter-parent提供的依赖管理,但是我又不想继承他,因为我还要继承别的项目,这时候该怎么办呢?

maven和Java一样都是单继承机制,maven当中有pom和import ,通过这两个标签在dependencyManagement中声明依赖,可以替代继承(达到类似parent标签的作用,解决了单继承问题)。

官网讲解:https://docs.spring.io/spring-boot/maven-plugin/using.html

在这里插入图片描述

<dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.3.2.RELEASE</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>类似于<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version><relativePath/>
</parent>

注意:使用dependencyManagement来替代parent的时候,pluginManagement里面嵌套的plugins版本并没有继承过来。

总结

推荐自定义dependencies,不使用spring-boot-dependencies,版本控制更加灵活,spring-boot-dependencies中不存在的依赖也可以添加进去,版本依赖进行升级时,自主控制,不会出现多个子模块使用同一依赖项版本不一致的情况,降低依赖冲突的几率。


http://www.ppmy.cn/news/1523933.html

相关文章

【论文阅读】DETRs Beat YOLOs on Real-time Object Detection

文章目录 摘要一、介绍二、相关工作2.1 实时目标检测器2.2 端到端目标检测器 三、检测器的端到端速度3.1 分析 NMS3.2 端到端速度基准 四、实时 DETR4.1 模型概述4.2 高效混合编码器4.3不确定性最小的查询选择4.4 缩放的RT - DETR 五、实验5.1 与SOTA对比5.2 混合编码器的消融研…

信号完整性仿真中关于铜箔粗糙度的三篇文献

首先放文献&#xff1a; Paul G. Huray. "Surface Roughness", in The Foundations of Signal Integrity. John Wiley & Sons, Inc., Hoboken, New Jersey. 2009. Paul G. Huray. "Impact of Copper Surface Texture on Loss: A model That Works", …

PostgreSQL 日常SQL语句查询记录

记录开发过程中使用的各种SQL语句&#xff01; 创建扩展 CREATE EXTENSION POSTGIS; CREATE EXTENSION POSTGIS_RASTER; 查询扩展 SELECT name, default_version, installed_version FROM pg_available_extensions; 查询具体某个函数 -- 查询具体的函数 例如&#xff1a;s…

【吉利汽车安全应急响应中心-登录/注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

小程序事件函数传参

mark传参 注意点&#xff1a;与data-*属性不同&#xff0c;mark属性可以包含从触发事件的节点到根节点上所有的mark属性值。如果你在一个嵌套组件中触发了事件&#xff0c;你不仅可以获取到当前组件的mark数据&#xff0c;还可以获取到其父组件乃至根组件上绑定的mark数据 1.…

XSS和sql注入部分场景测试用例样例

目录 1. SQL 注入测试用例设计 基本 SQL 注入 复杂 SQL 注入 盲注测试 2. XSS 攻击测试用例设计 基本 XSS 攻击 复杂 XSS 攻击 DOM-based XSS 1. SQL 注入测试用例设计 SQL 注入攻击通常通过在输入字段中插入恶意 SQL 代码&#xff0c;试图操纵数据库查询。设计这些测试…

在Ubuntu 20.04上安装Nginx的方法

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 简介 Nginx 是世界上最流行的 Web 服务器之一&#xff0c;负责托管互联网上一些最大和流量最高的网站。它是一个轻量级选择&#xff0c…

IP学习-Sixday

访问控制列表&#xff1a; 算是一种工具 作用&#xff1a;选择&#xff08;基于条件选择&#xff09; 方向&#xff1a;入方向&#xff0c;出方向 构成&#xff1a;1.编号 华为&#xff08;标准&#xff1a;2000-2999&#xff0c;高级&#xff1a;3000-3999&#xff09; 思…