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.
假定有如下依赖树结构:
A - > B - > C - > D 1.4 and A - > E - > D 1.0 |
基于最近定义原则,项目 A 将会依赖 D 1.0 版本。如果要指定使用 D 1.4 版本,可以在项目 A pom.xml 中显示指定 dependency 。
1.4、传递覆盖问题
包版本优先级顺序如下:
- 当前项目 pom 直接声明的包版本
- parent 项目声明的包版本
- 导入 POM (即 BOM 项目)声明的包版本,如果有多个导入按 import 顺序解析。
- 依赖调解机制
- 可以在当前项目 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
<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).
参考:
-
Spring with Maven BOM:https://www.baeldung.com/spring-maven-bom(推荐阅读)
- 官方 Maven 依赖机制介绍:https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
-
Maven 与Spring BOM(Bill Of Materials)简化Spring版本控制:https://blog.csdn.net/fanxiaobin577328725/article/details/66974896
-
Maven Spring BOM (bill of materials):http://www.cnblogs.com/YLsY/p/5711103.html