1、概述

1.1、什么是 BOM?

BOM stands for Bill Of Materials. A BOM is a special kind of POM that is used to control the versions of a project’s dependencies and provide a central place to define and update those versions.

BOM provides the flexibility to add a dependency to our module without worrying about the version that we should depend on.

1.2、BOM 的作用

Maven 支持单继承(即 parent 只能有一个),为更好的对依赖进行分组管理,可以通过 BOM 依赖导入机制实现。

1.3、传递依赖问题

如果项目有多个依赖,导致包版本出现冲突,Maven 会如何处理?

The answer here is the “nearest definition”. This means that the version used will be the closest one to our project in the tree of dependencies. This is called dependency mediation.

依赖调解机制:最近定义原则。

假定有如下依赖树结构:

-> B -> C -> D 1.4  and  -> E -> D 1.0

基于最近定义原则,项目 A 将会依赖 D 1.0 版本。如果要指定使用 D 1.4 版本,可以在项目 A pom.xml 中显示指定 dependency 。

1.4、传递覆盖问题

包版本优先级顺序如下:

  1. 当前项目 pom 直接声明的包版本
  2. parent 项目声明的包版本
  3. 导入 POM (即 BOM 项目)声明的包版本,如果有多个导入按 import 顺序解析。
  4. 依赖调解机制
    • 可以在当前项目 pom 显示指定包版本,用于覆盖依赖的包版本
    • 如果在导入的多个 BOM 项目中相同包存在多个版本,则使用声明在先的 BOM 项目中指定的包版本

2、使用

(1)定义BOM 项目,其 pom.xml 如下所示:

Project X:

<project>
 <modelVersion>4.0.0</modelVersion>
 <groupId>maven</groupId>
 <artifactId>X</artifactId>
 <packaging>pom</packaging>
 <name>X</name>
 <version>1.0</version>
 <dependencyManagement>
   <dependencies>
     <dependency>
       <groupId>test</groupId>
       <artifactId>a</artifactId>
       <version>1.1</version>
     </dependency>
     <dependency>
       <groupId>test</groupId>
       <artifactId>b</artifactId>
       <version>1.0</version>
       <scope>compile</scope>
     </dependency>
   </dependencies>
 </dependencyManagement>
</project>

说明:projext X 对 a(1.1版本)、b (1.0版本)进行管理。

Project Y:

<project>
 <modelVersion>4.0.0</modelVersion>
 <groupId>maven</groupId>
 <artifactId>Y</artifactId>
 <packaging>pom</packaging>
 <name>Y</name>
 <version>1.0</version>
 <dependencyManagement>
   <dependencies>
     <dependency>
       <groupId>test</groupId>
       <artifactId>a</artifactId>
       <version>1.2</version>
     </dependency>
     <dependency>
       <groupId>test</groupId>
       <artifactId>c</artifactId>
       <version>1.0</version>
       <scope>compile</scope>
     </dependency>
   </dependencies>
 </dependencyManagement>
</project>

说明:projext Y 对 a(1.2版本)、b (1.0版本)进行管理。

(2)在具体项目 pom dependencyManagement 中通过指定 type=pom,scope=import 方式导入 BOM 项目的依赖。

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>maven</groupId>
  <artifactId>Z</artifactId>
  <packaging>pom</packaging>
  <name>Z</name>
  <version>1.0</version>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>maven</groupId>
        <artifactId>X</artifactId>
        <version>1.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>maven</groupId>
        <artifactId>Y</artifactId>
        <version>1.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

说明:

  • Project Z 导入 X、Y 两个 BOM 项目,由于 X、Y 都定义有 a、b 依赖,按依赖导入顺序选择指定 a、b 版本,故 Z 依赖 a 1.1版本、b 1.0版本。

3、场

Spring BOM

Maven "Bill Of Materials" Dependency:

  It is possible to accidentally(意外地) mix different versions of Spring JARs when using Maven. For example, you may find that a third-party(第三方) library, or another Spring project, pulls in atransitive dependency(传递依赖) to an older release. If you forget to explicitly(明确地) declare(声明) a direct(直接) dependency yourself, all sorts of unexpected issues can arise(可能出现各种意想不到的问题).

  To overcome(克服) such problems Maven supports the concept of a "bill of materials" (BOM) dependency. You can import the spring-framework-bom in your dependencyManagement section to ensure(确保) that all spring dependencies (both direct and transitive) are at the same version.

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

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

An added benefit of using the BOM(使用BOM的附加好处) is that youno longer need(不再需要) to specify(详细说明) the <version> attribute(属性) when depending on Spring Framework artifacts:

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
    </dependency>
<dependencies>

Dubbo BOM

Github:https://github.com/apache/incubator-dubbo

为了防止用户不同的项目依赖了不同版本的 Dubbo 依赖,通过 Maven BOM来解决这一问题。在依赖管理时,引入 dubbo-dependencies-bom :
<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>dubbo-dependencies-bom</artifactId>
                <version>2.6.4</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>

注意事项

Finally, when creating projects that import dependencies beware of the following:

  • Do not attempt to import a pom that is defined in a submodule of the current pom. Attempting to do that will result in the build failing since it won't be able to locate the pom.
  • Never declare the pom importing a pom as the parent (or grandparent, etc) of the target pom. There is no way to resolve the circularity and an exception will be thrown.
  • When referring to artifacts whose poms have transitive dependencies the project will need to specify versions of those artifacts as managed dependencies. Not doing so will result in a build failure since the artifact may not have a version specified. (This should be considered a best practice in any case as it keeps the versions of artifacts from changing from one build to the next).

参考:

【转载】Maven中的BOM概念的更多相关文章

  1. maven使用.02.一些概念

    在上一篇POST中,简要的介绍了一下maven的特点,优势,安装.并建立了一个简单地Hello world工程.这一篇POST中,将主要会介绍一下Maven的一些约定. pom.xml文件 Maven ...

  2. 【转载】【时序约束学习笔记1】Vivado入门与提高--第12讲 时序分析中的基本概念和术语

    时序分析中的基本概念和术语 Basic concept and Terminology of Timing Analysis 原文标题及网址: [时序约束学习笔记1]Vivado入门与提高--第12讲 ...

  3. [转载]maven基础入门

    用 Maven 做项目构建 本文转载自:https://www.ibm.com/developerworks/cn/java/j-lo-maven/ 本文将介绍基于 Apache Maven 3 的项 ...

  4. Ant,Maven与Gradle的概念的理解

    转载地址:http://www.jianshu.com/p/cd8fe9b16369# 我们还是以AndroidStudio 2.1.1为例来讲. 用AndroidStudio就逃不开跟Gradle打 ...

  5. Unicode规范中的BOM 和 ISO8891-1编码

    Unicode规范中的BOM Unicode规范中有一个BOM的概念.BOM——Byte Order Mark,就是字节序标记.在这里找到一段关于BOM的说明: 在UCS 编码中有一个叫做" ...

  6. 【Java EE 学习 82 下】【MAVEN整合Eclipse】【MAVEN的一些高级概念】

    一.MAVEN整合Eclipse MAVEN是非常优秀,但是总是要开命令行敲命令是比较不爽的,我们已经习惯了使用IDE,所以还有一种将MAVEN整合到Eclipse的方法. 详情查看:http://w ...

  7. opnet仿真过程中SEED的概念问题 分类: opnet 2014-11-02 15:25 69人阅读 评论(0) 收藏

    仿真配置中SEED的概念:仿真随机种子,是产生随机数的种子值,反应随机数的状态.只要选定一个种子值,整个随机事件系统就固定了,复杂仿真的随机过程就成了一次实现.目的是测试仿真系统的稳健性,具体来说,针 ...

  8. Maven中基于POM.xml的Profile来动态切换配置信息

    [转载:https://blog.csdn.net/blueheart20/article/details/52838093] 1. Maven中的profile设置 Maven是目前主流的项目代码结 ...

  9. 034 Maven中的dependencyManagement和dependencies区别

    这个标签使用过,但是具体的描述还是没有说明过.在这里,专门查了一下,写了这篇文章. 1.定义 在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管 ...

随机推荐

  1. Linux中系统检测工具top命令

    Linux中系统检测工具top命令 本文转自:https://www.cnblogs.com/zhoug2020/p/6336453.html 首先介绍top中一些字段的含义: VIRT:virtua ...

  2. GWAS | 全基因组关联分析 | Linkage disequilibrium (LD)连锁不平衡 | 曼哈顿图 Manhattan_plot | QQ_plot | haplotype phasing

    现在GWAS已经属于比较古老的技术了,主要是碰到严重的瓶颈了,单纯的snp与表现的关联已经不够,需要具体的生物学解释,这些snp是如何具体导致疾病的发生的. 而且,大多数病找到的都不是个别显著的snp ...

  3. c#万能视频播放器

    http://blog.csdn.net/yanzhibo/article/details/8972822 本人之前很多的文章中均提到了使用libvlc为播放器内核制作的播放器,也许有些朋友对此感兴趣 ...

  4. (Gorails) activeStore模块,把一堆属性放在一个hash对象内。gem 'activerecord-typedstore'增强了store模块,更好用了

    https://api.rubyonrails.org/classes/ActiveRecord/Store.html https://gorails.com/episodes/preferences ...

  5. canvas手机端绘图解决方案

    解决方案js:https://pan.baidu.com/s/1jIys2aU 我们使用canvas通常会遇到一个问题就是坐标系的问题,如果按象限来说,一般canvas是在第四象限,但是我们通常都喜欢 ...

  6. PTA L2-002 链表去重

    题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805072641245184 第一次做链表题,有时间多看看 解释 ...

  7. Spring缓存注解

    从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该 ...

  8. 【JS】【4】字符串数字比较大小

    两个转换函数: parseInt():把值转换成整数 parseFloat():把值转换成浮点数 也有其他方法,详情请看参考博客,但个人认为转换函数是最好的方法 参考文档: 1,js.jquery字符 ...

  9. SpringBoot项目Shiro的实现(一)

    一.Shiro的简单介绍 Shiro是Apache下的一个开源项目,我们称之谓Apache Shiro,它是一个易用与Java项目的安全框架,提供了认证.授权.加密.会话管理,与Spring Secu ...

  10. 1013. Pairs of Songs With Total Durations Divisible by 60总持续时间可被 60 整除的歌曲

    网址:https://leetcode.com/problems/pairs-of-songs-with-total-durations-divisible-by-60/submissions/ 参考 ...