what BOM?

BOM(Bill of Materials)是由Maven提供的功能,它通过定义一整套相互兼容的jar包版本集合,

使用时只需要依赖该BOM文件,即可放心的使用需要的依赖jar包,且无需再指定版本号

BOM的维护方负责版本升级,并保证BOM中定义的jar包版本之间的兼容性。

why BOM?

使用BOM除了可以方便使用者在声明依赖的客户端时不需要指定版本号外,

最主要的原因是可以解决依赖冲突,如考虑以下的依赖场景:

项目A依赖项目B 2.1和项目C 1.2版本:

项目B 2.1依赖项目D 1.1版本;

项目C 1.2依赖项目D 1.3版本;

在该例中,项目A对于项目D的依赖就会出现冲突,按照maven dependency mediation的规则,最后生效的可能是:项目A中会依赖到项目D1.1版本(就近原则,取决于路径和依赖的先后,和Maven版本有关系)。

在这种情况下,由于项目C依赖1.3版本的项目D,但是在运行时生效的确是1.1版本,

所以在运行时很容易产生问题,如 NoSuchMethodError, ClassNotFoundException等,

有些jar包冲突定位还是比较难的,这种方式可以节省很多定位此类问题的时间。

Spring、SpringBoot、SpringCloud自身都采用了此机制来解决第三方包的冲突,

常见官方提供的BOM:

1) RESTEasy Maven BOM dependency

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-bom</artifactId>
<version>3.0.6.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

2. JBOSS Maven BOM dependency

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.bom</groupId>
<artifactId>jboss-javaee-6.0-with-tools</artifactId>
<version>${some.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

3) Spring Maven BOM dependency

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.0.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

4) Jersey Maven BOM dependency

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

5) SpringCloud SpringBoot Maven BOM dependency

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.4.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2020.0.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

看着有点蒙不要紧,下面会详细介绍这些配置的作用

自己开发的项目中也建议使用此优良传统, 尤其实在项目开发初期,在后期再修改成BOM可能涉及很多版本的修改,就比较难了。

how BOM?

定义BOM

BOM本质上是一个普通的POM文件,区别是对于使用方而言,生效的只有 <dependencyManagement>这一个部分。

只需要在<dependencyManagement>定义对外发布的客户端版本即可,

比如需要在项目中统一所有SpringBoot和SpringCloud的版本

第一步需要在POM文件中增加两个的官方BOM,以目前最新稳定的SpringBoot版本为例,使用官方推荐的版本组合比较稳定,一般不会有什么大的问题

<groupId>com.niu.not</groupId>
<artifactId>niu-dependency</artifactId>
<version>1.1.1</version>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.4.6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2020.0.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
</dependencies>

下面的Gson是除了SpringBoot和SpingCloud外需要统一版本的jar

其他工程使用方法

在项目主pom.xml文件中<dependencyManagement></dependencyManagement>节点下加入BOM的GAV信息如下:

<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.niu.not</groupId>
<artifactId>niu-dependency</artifactId>
<version>1.1.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

在需要使用相关JAR包的pom.xml文件中<dependencies></dependencies>节点下引入如下:

<dependencies>
<!--此时用到Spring和Gson都不需要加版本号,会自动引用BOM中提供的版本-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
</dependencies>

这种设置后,如果项目要求升级Spring版本,只需要在提供方升级验证兼容性,然后修改BOM依赖即可

如果需要使用不同于当前bom中所维护的jar包版本,则加上<version>覆盖即可,如:

<dependencies>
<!--此时用到Spring和Gson都不需要加版本号,会自动引用BOM中提供的版本-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<!--会覆盖掉BOM中声明的版本2.8.6,使用自定义版本2.8.2-->
<version>2.8.2</version>
</dependency>
</dependencies>

小结

Jar包冲突非常烦人,Spring框架相关的冲突,有些报错非常不清晰或者根本不报错直接停止服务,

这种问题很难定位,开发人员应该聚焦业务开发,不应该在这上面浪费过多时间,

所以统一的版本管理还是非常有用的,不然Spring的牛逼框架为啥都在用呢,

BOM管理,拿来吧你!!!

参考:https://howtodoinjava.com/maven/maven-bom-bill-of-materials-dependency/

Maven BOM!拿来吧你的更多相关文章

  1. 【jar包管理】Maven BOM

    BOM Alibaba Spring Boot Dependencies is a Maven BOM used to manage the versions of most used Alibaba ...

  2. Java 使用 Maven BOM 统一管理版本号

    一个中大型的 Java 项目往往包含若干 JAR 包,这些 JAR 包有着不同的版本号.如果这些 JAR 包单独发布,然后直接通过版本号引用相应的 JAR 包,不同版本的兼容性维护将变得十分麻烦.为了 ...

  3. 【转载】Maven中的BOM概念

    1.概述 1.1.什么是 BOM? BOM stands for Bill Of Materials. A BOM is a special kind of POM that is used to c ...

  4. Maven Spring BOM (bill of materials)

    为了防止用Maven管理Spring项目时,不同的项目依赖了不同版本的Spring,可以使用Maven BOM来解决者一问题. 在依赖管理时,引入spring-framework-bom,如: < ...

  5. Dubbo 入门之二 ——- 项目结构解析

    本文主要说明点 概述 背景 需求 架构 Dubbo源代码项目结构 概述 分享 Dubbo 的项目结构 ,通过本文可以大致了解到Dubbo整个项目的结构 背景 将一个项目进行拆分, 进行分布式架构. 需 ...

  6. 【Spring Boot && Spring Cloud系列】Spring Boot的启动器Starter

    Spring Boot的内置Servlet Container: Name Servlet Version Java Version Tomcat8 3.1 Java 7+ Tomcat7 3.0 J ...

  7. 给Swagger换一套皮肤 Knife4j集成记录

    Swagger有一套经典的UI,但是并不是很好用,之前有看到Knife4j,界面没管.功能完善,因此尝试集成. demo参考示例地址:knife4j-spring-boot-demo Knife4j前 ...

  8. Reactor3 中文文档(用户手册)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

  9. SpringCloud微服务实战——搭建企业级开发框架(六):使用knife4j集成Swagger2接口文档

    knife4j是为集成Swagger生成api文档的增强解决方案,前后端Java代码以及前端Ui模块进行分离,在微服务架构下使用更加灵活, 提供专注于Swagger的增强解决方案,不同于只是改善增强前 ...

随机推荐

  1. 用TensorRT针对AArch64用户的交叉编译示例

    用TensorRT针对AArch64用户的交叉编译示例 以下介绍如何在x86_64linux下为AArch64 QNX和Linux平台交叉编译TensorRT示例. 2.1. Prerequisite ...

  2. A,B,C,D分别为不同的整数,满足以下乘法公式,求A,B,C,D的值

    问题:A,B,C,D分别为不同的整数,满足以下乘法公式,求A,B,C,D的值 解题思路: 由题意可知A,B,C,D为不同的整数,则A!=B,A!=C,A!=D,B!=C,B!=D,C!=D 再由给出公 ...

  3. 『动善时』JMeter基础 — 40、JMeter中ForEach控制器详解

    目录 1.什么是逻辑控制器 2.ForEach控制器介绍 3.ForEach控制器的使用 (1)测试计划内包含的元件 (2)获取学院列表请求内容 (3)JSON提取器内容 (4)ForEach控制器内 ...

  4. Ubuntu18.04的下载与安装(全过程纪录)

    unbuntu18.04的下载与安装 注:由于大部分过程是以图片形式说明,所以可能会导致网页浏览不流畅 前言 有时候由于个人计算机中文件的频繁移动,导致虚拟机的镜像文件有时候莫名删除了或者不见了(说到 ...

  5. Vim一直学不会?试试这个 "真香" 神器

    Vim 的使用,一直以来是一个难题 以至于国外的知名程序员问答社区 StackOverFlow 上有一个问题 How to I exit the Vim editor 获得了超过 200万次的浏览量 ...

  6. Android Gradle插件

    目录 什么是Gradle 编写方法 buildSrc 基础概念 Extension 自定义Task Plugin Transformer Gradle用处 好文章 常见问题 Gradle插件练习地址: ...

  7. 【dp】状压dp

    二进制的力量 状态压缩DP 愤怒的小鸟 第一次接触状态压缩DP是在NOIP2016的愤怒的小鸟,当时菜得连题目都没看懂,不过现在回过头来看还是挺简单的,那么我们再来看看这道题吧. 题意&数据范 ...

  8. NOIP模拟测试3「序列·熟练剖分·建造游乐园(play)」

    ---恢复内容开始--- 序列 刚调出来样例就A了,假装是水题. 因为是乱序,我们要求出来每两项之间最小公比,而不是直接比 求出来每两项之间最小公比,然后扫一遍就完了.(还要注意重复情况) 那么问题就 ...

  9. Linux命令大全之搜索命令

    文件搜索命令(只能搜索文件) locate 文件名 在后台数据库中按文件名搜索,搜索速度快      /var/lib/mlocate(locate文件数据库)    这个数据库默认一天更新一次,强制 ...

  10. 连接过的WiFi改了密码之后再次连接不让输入新密码还是用旧密码一直显示连接失败

    设置---网络和Internet---WLAN----管理已知网络----忘记    根据这个步骤就能忘记密码,重新输入新密码了.