依赖管理之BOM

本文详细介绍了BOM(材料清单)的概念、格式以及如何在项目中使用。BOM实际上是一个特殊的POM文件,它列出了一个工程的所有依赖及其对应版本,便于其他工程引用而无需指定具体版本。文章通过一个具体的BOM文件示例,解释了其关键信息和结构,包括打包方式、依赖管理等。

6 分钟1.1k 字

依赖管理之BOM开发与工程 · 6 分钟

#问题

  1. 什么是 BOM
  2. BOM格式是什么
  3. 怎么在项目中使用BOM

#什么是 BOM

BOM 全称是 Bill Of Materials,译作材料清单。BOM 本身并不是一种特殊的文件格式,而是一个普通的 pom 文件,只是在这个 POM 中,我们罗列的是一个工程的所有依赖和其对应的版本。该文件一般被其它工程使用,当其它工程引用 BOM 中罗列的 jar 包时,不用显示指定具体的版本,会自动使用 BOM 对应的 jar 版本。

所以 BOM 的好处是用来管理一个工程的所有依赖版本信息。

#BOM 的格式

xmlxml折叠展开
<?xml version="1.0" encoding="UTF-8"?><project xmlns:xsi="<http://www.w3.org/2001/XMLSchema-instance>"         xmlns="<http://maven.apache.org/POM/4.0.0>"         xsi:schemaLocation="<http://maven.apache.org/POM/4.0.0> <http://maven.apache.org/xsd/maven-4.0.0.xsd>">    <modelVersion>4.0.0</modelVersion>     <groupId>com.vitahlin</groupId>    <artifactId>janna-bom</artifactId>    <!--BOM清单中不能使用revision-->    <version>${bom.version}</version>    <packaging>pom</packaging>     <properties>        <bom.version>1.0-SNAPSHOT</bom.version>        <maven.compiler.source>17</maven.compiler.source>        <maven.compiler.target>17</maven.compiler.target>        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>        <encoding>UTF-8</encoding>         <lombok.version>1.18.26</lombok.version>    </properties>     <dependencyManagement>        <dependencies>            <dependency>                <groupId>org.projectlombok</groupId>                <artifactId>lombok</artifactId>                <version>${lombok.version}</version>                <scope>provided</scope>            </dependency>        </dependencies>    </dependencyManagement></project>

其中的关键信息是:

  • <packaging>pom</packaging> 打包方式是 pom 文件
  • <dependencyManagement><dependencies> 下定义的各种依赖的版本

#怎么引用 BOM

一般情况下,是在项目主 pom 中引入 BOM,比如 parent 的 pom 文件:

xmlxml折叠展开
<?xml version="1.0" encoding="UTF-8"?><project xmlns:xsi="<http://www.w3.org/2001/XMLSchema-instance>"         xmlns="<http://maven.apache.org/POM/4.0.0>"         xsi:schemaLocation="<http://maven.apache.org/POM/4.0.0> <http://maven.apache.org/xsd/maven-4.0.0.xsd>">    <modelVersion>4.0.0</modelVersion>     <groupId>com.vitahlin</groupId>    <artifactId>janna</artifactId>    <version>${revision}</version>    <packaging>pom</packaging>    <modules>        <module>janna-basis</module>        <module>janna-bom</module>    </modules>     <properties>        <maven.compiler.source>17</maven.compiler.source>        <maven.compiler.target>17</maven.compiler.target>        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>        <revision>1.0-SNAPSHOT</revision>        <bom.version>1.0-SNAPSHOT</bom.version>    </properties>     <dependencyManagement>        <dependencies>            <dependency>                <groupId>com.vitahlin</groupId>                <artifactId>janna-bom</artifactId>                <version>${bom.version}</version>                <type>pom</type>                <scope>import</scope>            </dependency>        </dependencies>    </dependencyManagement></project>

在需要使用相关 JAR 包的 pom.xml 文件中 <dependencies></dependencies> 节点下引入依赖的 groupId 和 artifactId 即可,如:

xmlxml折叠展开
<?xml version="1.0" encoding="UTF-8"?><project xmlns:xsi="<http://www.w3.org/2001/XMLSchema-instance>"         xmlns="<http://maven.apache.org/POM/4.0.0>"         xsi:schemaLocation="<http://maven.apache.org/POM/4.0.0> <http://maven.apache.org/xsd/maven-4.0.0.xsd>">    <modelVersion>4.0.0</modelVersion>    <parent>        <groupId>com.vitahlin</groupId>        <artifactId>janna</artifactId>        <version>${revision}</version>    </parent>    <artifactId>janna-basis</artifactId>     <properties>        <maven.compiler.source>17</maven.compiler.source>        <maven.compiler.target>17</maven.compiler.target>    </properties>     <dependencies>        <dependency>            <groupId>org.projectlombok</groupId>            <artifactId>lombok</artifactId>        </dependency>    </dependencies></project>

这时候,就能发现 janna-basis 模块直接引入了 lombok 依赖,并且版本就是在 janna-bom 中定义的版本。这样设置后,如果项目要求升级 lombok 的版本,只需要在提供方升级验证兼容性,然后修改 BOM 依赖即可

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

xmlxml折叠展开
<dependencies>    <dependency>        <groupId>org.projectlombok</groupId>        <artifactId>lombok</artifactId>        <version>1.18.24</version>        <scope>provided</scope>    </dependency></dependencies>

#版本冲突时的一些规则

当出现版本冲突时,具体使用哪一个版本的优先顺序是:

  1. 直接在当前工程中显示指定的版本
  2. parent 中配置的父工程使用的版本
  3. 在当前工程中通过 dependencyManagement 引入的 BOM 清单中的版本,当引入的多个 BOM 都有对应 jar 包时,先引入的 BOM 生效
  4. 上述三个地方都没配置,则启用依赖调解 dependency mediation

什么是依赖调解? Dependency mediation(依赖调解)是指在多模块或多组件系统中,如何选择和解决不同版本的依赖关系。当项目或应用程序中引用了多个依赖,而这些依赖之间可能有版本冲突时,依赖调解的作用就是决定最终使用哪一个版本的依赖,以保证系统的稳定性和兼容性。

Maven 在面对版本冲突时,会选择“最近的依赖”(即根据依赖树的深度来选择),或者通过指定明确的版本来解决。 当有两个依赖路径,依赖到同一个 jar 的不同版本时,最短路径的版本生效。假设有如下依赖关系:

shellshell折叠展开
A -> B -> C -> D 1.4A -> E -> D 1.0

在 Maven 中,最终会选择 D 的 1.4 版本,而不是 1.0 版本,因为 D 1.4 是通过路径 A -> B -> C -> D 1.4 被依赖的,而这个路径比 A -> E -> D 1.0 更长,所以 Maven 会选择版本较新的 D 1.4。

END · 2026.02.04
你可能也想读
IDEA编译jdk8并且在源码中执行printf2026.02.04 · 14 分钟↗macOS上Java开发环境搭建2026.02.04 · 1 分钟↗ClassPathResource报错cannot be resolved to absolute file path2026.02.04 · 2 分钟↗
林
VitahLin

后端工程师 · 写长文
VitahLin 的个人博客,记录经济观察、股票研究,以及后端开发、分布式系统、数据库与 Redis 的原理和工程实践。