一个中大型的 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<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。
使用的时候需要在 dependencies 下面引入 BOM,然后在 constraints 下面声明要使用的库,声明的时候无须指定版本。另外,需要在 configurations 中调用 javaPlatform.allowDependencies(),否则会报错。
configurations{
javaPlatform.allowDependencies()
}
dependencies {
api platform("org.springframework.boot:spring-boot-dependencies:2.4.4")
constraints {
api "org.apache.kafka:kafka-clients:2.6.0"
api "redis.clients:jedis:3.5.2"
api "org.springframework.batch:spring-batch-core"
}
}
3 参考
[1] Introduction to the Dependency Mechanism
[2] The Java Platform Plugin
到此这篇关于Java使用Maven BOM统一管理版本号的实现的文章就介绍到这了,更多相关Maven BOM统一管理版本号内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!