Maven BOM And POM

概述

在本快速教程中,我们将了解基于项目对象模型(POM)概念的工具 Maven 如何使用 BOM 或 "物料清单"。

有关 Maven 的更多详情,请查看我们的文章《Apache Maven 教程》

依赖性管理概念

要了解什么是 BOM 以及 BOM 的用途,我们首先需要学习一些基本概念。

什么是 Maven POM

Maven POM 是一个 XML 文件,其中包含(关于项目的)信息和配置,Maven 使用这些信息和配置来导入依赖关系并构建项目。

什么是 Maven BOM

BOM 是 Bill Of Materials(物料清单)的缩写。BOM 是一种特殊的 POM,用于控制项目依赖项的版本,并为定义和更新这些版本提供一个中心位置。

BOM 提供了为模块添加依赖关系的灵活性,而无需担心依赖关系的版本问题。

跨依赖关系

Maven 可以发现 pom.xml 中我们自己的依赖项所需的库,并自动包含它们。收集库的依赖级别数量没有限制。

当两个依赖项指向特定工程的不同版本时,就会产生冲突。Maven 会包含哪一个?
答案是 "最接近的定义"。这意味着所使用的版本将是依赖关系树中最接近我们项目的版本。这就是所谓的 "依赖调解"。

让我们通过下面的示例来了解依赖关系调解:

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

本例显示项目 A 依赖于 B 和 E。B 和 E 有各自的依赖关系,它们会遇到不同版本的 D 模块。在构建 A 项目时将使用 D 1.0,因为通过 E 的路径更短。

有不同的技术来确定应包含哪个版本的模块:

  • 我们总是可以通过在项目的 POM 中明确声明来保证版本。例如,为了保证使用 D 1.4,我们应在 pom.xml 文件中将其明确添加为依赖项。
  • 我们可以使用 "依赖关系管理 "部分来控制模块版本,本文稍后将对此进行说明。

依赖关系管理

简而言之,依赖关系管理是一种集中管理依赖关系信息的机制。

当我们有一组继承了共同父项目的项目时,我们可以将所有依赖关系信息放在一个名为 BOM 的共享 POM 文件中。

下面是一个如何编写 BOM 文件的示例:

xml 复制代码
<project ...>

  <modelVersion>4.0.0</modelVersion>
  <groupId>baeldung</groupId>
  <artifactId>Baeldung-BOM</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>
  <name>BaelDung-BOM</name>
  <description>parent pom</description>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>test</groupId>
        <artifactId>a</artifactId>
        <version>1.2</version>
      </dependency>
      <dependency>
        <groupId>test</groupId>
        <artifactId>b</artifactId>
        <version>1.0</version>
        <scope>compile</scope>
      </dependency>
      <dependency>
        <groupId>test</groupId>
        <artifactId>c</artifactId>
        <version>1.0</version>
        <scope>compile</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

我们可以看到,BOM 是一个普通的 POM 文件,其中有一个依赖管理(dependencyManagement)部分,我们可以在该部分中包含模块的所有信息和版本。

使用 BOM 文件

有两种方法可以在项目中使用之前的 BOM 文件,这样我们就可以声明我们的依赖关系,而不必担心版本号问题。

我们可以从父类继承:

xml 复制代码
<project ...>
    <modelVersion>4.0.0</modelVersion>
    <groupId>baeldung</groupId>
    <artifactId>Test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>Test</name>
    <parent>
        <groupId>baeldung</groupId>
        <artifactId>Baeldung-BOM</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
</project>

我们可以看到,我们的项目 Test 继承了 Baeldung-BOM。
我们还可以导入 BOM。

在大型项目中,继承的方法并不有效,因为项目只能继承一个父项目。导入是另一种选择,因为我们可以根据需要导入任意数量的 BOM。

让我们看看如何将 BOM 文件导入项目 POM:

xml 复制代码
<project ...>
    <modelVersion>4.0.0</modelVersion>
    <groupId>baeldung</groupId>
    <artifactId>Test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>Test</name>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>baeldung</groupId>
                <artifactId>Baeldung-BOM</artifactId>
                <version>0.0.1-SNAPSHOT</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

重写 BOM 依赖关系

模块版本的优先顺序是

  1. 在我们的项目 pom 中直接声明的模块版本
  2. 模块在父项目中的版本
  3. 考虑到导入文件的顺序,导入 pom 中的版本
  4. 依赖关系调解

我们可以在项目 pom 中用所需的版本明确定义模块,从而覆盖模块的版本。

如果同一个模块在两个导入的 BOM 中定义了不同的版本,那么先声明的 BOM 文件中的版本将胜出

Spring BOM

我们可能会发现,第三方库或其他 Spring 项目会拉入对旧版本的传递依赖关系。如果我们忘记明确声明直接依赖关系,就会出现意想不到的问题。

为了克服此类问题,Maven 支持 BOM 依赖性概念。

我们可以在依赖关系管理(dependencyManagement)部分导入 spring-framework-bom,以确保所有 Spring 依赖关系都处于同一版本:

xml 复制代码
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-framework-bom</artifactId>
            <version>5.3.27</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

在下面的示例中,我们使用 Spring模块时无需指定版本属性:

xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
    </dependency>
<dependencies>

结论

在这篇短文中,我们介绍了 Maven的BOM概念,以及如何将模块信息和版本集中到一个通用的 POM 中。

简而言之,我们可以通过继承或导入来利用 BOM 的优势。

参考文档

相关推荐
Java&Develop25 分钟前
springboot + mysql8降低版本到 mysql5.7
java·spring boot·后端
sg_knight27 分钟前
从单体架构到微服务:架构演进之路
java·spring boot·spring·spring cloud·微服务·云原生·架构
武昌库里写JAVA41 分钟前
MacOS Python3安装
java·开发语言·spring boot·学习·课程设计
eternal__day1 小时前
Spring Cloud:构建云原生微服务架构的最佳工具和实践
java·spring cloud·微服务·云原生·架构
cdut_suye1 小时前
【Linux系统】从 C 语言文件操作到系统调用的核心原理
java·linux·数据结构·c++·人工智能·机器学习·云计算
forestsea1 小时前
Maven 插件参数注入与Mojo开发详解
java·maven·mojo
荔枝吻1 小时前
【抽丝剥茧知识讲解】引入mybtis-plus后,mapper实现方式
java·sql·mybatis
在未来等你1 小时前
互联网大厂Java求职面试:构建高并发直播平台的架构设计与优化
java·spring boot·微服务·kubernetes·高并发·分布式系统·直播平台
傻小胖2 小时前
json-server的用法-基于 RESTful API 的本地 mock 服务
后端·json·restful
轮到我狗叫了2 小时前
力扣.1471数组的k个最强值,力扣.1471数组的k个最强值力扣1576.替换所有的问号力扣1419.数青蛙编辑力扣300.最长递增子序列
java·数据结构·算法