BOM
What Is Maven 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.
在大型项目中,BOM 用于将一组相关的、可以良好协作的构建(Maven Artifact)组合在一起,提供版本管理,避免构件间潜在的版本不兼容风险。
BOM 配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 <project > <modelVersion > 4.0.0</modelVersion > <groupId > test</groupId > <artifactId > project-n-bom</artifactId > <version > 1.0</version > <packaging > pom</packaging > <properties... > <dependencyManagement... > </project >
BOM 引用如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 <dependencyManagement > <dependencies > <dependency > <groupId > io.github.openfeign</groupId > <artifactId > feign-bom</artifactId > <version > ${openfeign.version}</version > <type > pom</type > <scope > import</scope > </dependency > </dependencies > </dependencyManagement >
常用的 BOM 如下:https://mvnrepository.com/tags/bom
实践例子 <dependencyManagement>
用于在具有层级关系的项目间统一管理依赖的版本,一般用在父项目中,通过它来管理 jar 包的版本,让子项目中引用一个依赖而不用显式的指定版本号,以达到依赖版本统一管理 的目的。
这种方法的好处是显而易见的。依赖的细节(如版本号)可以在一个中心位置集中设置,并传播到所有继承的 POM。
但由于现实中有可能是 N 个项目都继承同一个父项目,如果把它们的依赖全部放到父项目的 <DependencyManagement>
中管理,势必会导致父项目的依赖配置急剧膨胀,形成一个巨型 POM。更为关键的是,后续各项目组都有升级各自提供的依赖版本的需要,如果大家都去改这个公共的父项目,版本管理会变得很混乱。
解决办法是按项目组粒度对依赖进行分组管理,分而治之。将每组依赖抽取成像 spring-boot-dependencies
一样的 BOM,并在父项目中 <dependencyManagement>
使用 scope=import
方式将这些 BOM 组合起来,这样父项目的 POM 就会十分干净且稳定,各组依赖的版本管理也能转由各自项目组的 BOM 专门负责,类似一个金字塔模型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 +------------+ | parent-pom | +------+-----+ | +-----------------|-----------------+ | | | +-------v-------+ +-------+-------+ +-------v-------+ | Project-A-BOM | | Project-B-BOM | | Project-N-BOM | +---------------+ +-------+-------+ +---------------+ | +--------------|---------------+ | | | +-----v------+ +-----v------+ +------v-----+ | Artifact-A | | Artifact-B | | Artifact-N | +------------+ +------------+ +------------+
例如某个公司的标准父项目 POM 如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <project > <modelVersion > 4.0.0</modelVersion > <groupId > test</groupId > <artifactId > parent</artifactId > <version > 1.0</version > <packaging > pom</packaging > <dependencyManagement > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-dependencies</artifactId > <version > 1.5.3.RELEASE</version > <type > pom</type > <scope > import</scope > </dependency > ...... </dependencies > </dependencyManagement > </project >
开发阶段为了测试 Spring Boot 2 的兼容性,该公司 child 项目新开 git 分支,修改 POM 如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <project > <modelVersion > 4.0.0</modelVersion > <parent > <groupId > test</groupId > <artifactId > parent</artifactId > <version > 1.0</version > </parent > <artifactId > child</artifactId > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > </dependencies > <dependencyManagement > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-dependencies</artifactId > <version > 2.0.1.RELEASE</version > <type > pom</type > <scope > import</scope > </dependency > </dependencies > </dependencyManagement > <build > <plugins > <plugin > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-maven-plugin</artifactId > </plugin > </plugins > </build > </project >
上例 child 项目覆盖了父项目 <dependencyManagement>
的 Spring Boot 版本,当兼容性测试通过后,子项目 <dependencyManagement>
即可去掉,转而升级父项目 Spring Boot 的版本号即可,这样所有子项目都会统一升级版本。
参考 https://en.wikipedia.org/wiki/Bill_of_materials
https://www.baeldung.com/spring-maven-bom
https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-build-systems.html
https://projectreactor.io/docs/core/release/reference/#getting-started-understanding-bom