Java 使用 Maven BOM 统一管理版本号

一个中大型的 Java 项目往往包含若干 JAR 包,这些 JAR 包有着不同的版本号。如果这些 JAR 包单独发布,然后直接通过版本号引用相应的 JAR 包,不同版本的兼容性维护将变得十分麻烦。为了解决这个问题,可以让一个特殊的模块引用这些 JAR 包,将版本号定义在这个模块中,模块中的 JAR 都是兼容的,对外发布时只发布这个特殊模块。这个特殊模块就是 BOM(Bill Of Materials)。

著名的 Spring Boot 就使用了这种方式来管理版本号,这个模块就是 spring-boot-dependencies,用户在使用 Spring Boot Starter 相关依赖时引入特定版本的 spring-boot-dependencies,然后在引入其它依赖时只需要声明 group 和 name 即可,不需要再指定版本号了。当然,在 Gradle 中使用 Spring Boot 插件,或者在 Maven 中使用 spring-boot-starter-parent 作为父模块也能够达到类似的效果。

本文将介绍如何通过 Gradle 来制作一个 BOM 以及如何在 Gradle 中使用 BOM。作为 Maven 中的一个概念,也可以使用 Maven 也可以制作和使用 BOM,但本文不涉及。

1. BOM 介绍

BOM (Bill Of Material) 是 Maven 仓库中的一个概念,它本质也是一个可被引用的包,但不包含代码,只是声明了一系列其它包。例如:Maven 中央仓库中的 spring-boot-dependencies](https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/2.4.4/) 包。它只有一个 .pom 文件。

下面是 Maven 官网上的一个简单的 BOM 的 .pom 文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 "> <modelVersion>4.0.0</modelVersion> <groupId>com.test</groupId> <artifactId>bom</artifactId> <version>1.0.0</version> <packaging>pom</packaging> <properties> <project1Version>1.0.0</project1Version> <project2Version>1.0.0</project2Version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>com.test</groupId> <artifactId>project1</artifactId> <version>${project1Version}</version> </dependency> <dependency> <groupId>com.test</groupId> <artifactId>project2</artifactId> <version>${project2Version}</version> </dependency> </dependencies> </dependencyManagement> <modules> <module>parent</module> </modules> </project>

这个文件声明了两个包(project1 和 project2)及其版本号,和一般 .pom 文件中的声明不同的是, 节点外面还包含了一层 节点。以上就是 BOM 包中最核心的文件的基本结构了;基于 Gradle 发布 BOM 包的本质就是生成这样的一个文件。

2. 使用 Gradle 制作一个 BOM

这里我们假定要创建一个 BOM,用来统一管理三方 Java 包,其它业务模块通过引用这个 BOM 来间接引用需要使用的第三方 Java 包。工程完整代码:https://github.com/Robothy/gradle-bom-example

2.1 创建 BOM 工程

Gradle 中的 BOM 工程需要使用 java-platform 插件,这样的工程是一个不包含源代码,只包含包声明的特殊的组件,也被称为平台(platform)。

build.gradle 部分代码

plugins { id 'java-platform' } dependencies { constraints { // 声明一些三方包及其版本号 api "org.apache.kafka:kafka-clients:2.6.0" api "redis.clients:jedis:3.5.2" } }

上面代码中,三方包的声明没有放在 dependencies 中,而是放在了 constraints 里面。这表示如果使用了其中的包,优先使用 constraints 中声明的版本。

BOM 项目中声明包的方式有两种:

api 表示包在编译期可见。

runtime 表示包在运行期间可见。

2.2 BOM 的发布

BOM 的发布需要使用 maven-publish 插件,其发布配置如下:

publishing { publications { thirdPartPlatform(MavenPublication){ from components.javaPlatform artifactId = "third-part-dependencies" } } repositories { mavenLocal() } }

BOM 的命名一般以 -dependencies 结尾,这里我们取名为 third-part-dependnecies。

执行 ./gradlew.bat publish 就可以将 BOM 发布到本地的 Maven 仓库了。发布的 artifacts 包含两个主要文件(.pom 和 .module)和若干校验文件。其中 .pom 的文件内容为 Maven 官方定义的 BOM 的标准格式,而 .module 文件内容是 Gradle 描述元数据的一种格式。

2.3 BOM 的使用

普通的 Java 应用或者 Java 库使用 BOM 的时候需要先添加 BOM 依赖,然后使用其它的库。例如:

// 引入 BOM implementation platform("org.example:third-part-dependencies:1.0") // 引入包,这时不需要再指定版本号 implementation "org.apache.kafka:kafka-clients"

当然,BOM 工程或者说 platform 工程也可以使用 BOM。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpppww.html