什么是 BOM
BOM 全称是 Bill Of Materials,译作材料清单。BOM 本身并不是一种特殊的文件格式,而是一个普通的 POM 文件,只是在这个 POM 中,我们罗列的是一个工程的所有依赖和其对应的版本。该文件一般被其它工程使用,当其它工程引用 BOM 中罗列的 jar 包时,不用显示指定具体的版本,会自动使用 BOM 对应的 jar 版本。
所以 BOM 的好处是用来管理一个工程的所有依赖版本信息。
BOM 的格式
<?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 文件:
<?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 即可,如:
<?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>
覆盖即可,如:
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
</dependencies>
版本冲突时的一些规则
当出现版本冲突时,具体使用哪一个版本的优先顺序是:
- 直接在当前工程中显示指定的版本
- parent 中配置的父工程使用的版本
- 在当前工程中通过 dependencyManagement 引入的 BOM 清单中的版本,当引入的多个 BOM 都有对应 jar 包时,先引入的 BOM 生效
- 上述三个地方都没配置,则启用依赖调解 dependency mediation
什么是依赖调节?
当有两个依赖路径,依赖到同一个 jar 的不同版本时,最短路径的版本生效,比如 A -> B -> C -> D 1.4 and A -> E -> D 1.0
最终将会使用 D 的 1.0版本。