什么是 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版本。