zoukankan      html  css  js  c++  java
  • Java 使用 Maven BOM 统一管理版本号

    一个中大型的 Java 基础框架项目往往包含许多 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

  • 相关阅读:
    使用RestTemplate进行服务调用的几种方式
    springmvc学习指南 之---第32篇 mybatis 嵌套的处理
    springmvc学习指南 之---第31篇 使用墨客进行测试报错
    springmvc学习指南 之---第30篇 异常的全局处理
    Effective Java 阅读笔记--之(一) 建造者模式(Builder)
    使用mybatis-generator.xml 生成PO 对象
    springmvc学习指南 之---第29篇 springmvc 返回json对象, 不想创建类的前提下
    springmvc学习指南 之---第28篇 springmvc的controller 如何解析视图view? 如何解析json,html,jsp?
    springmvc学习指南 之---第27篇 spring如何实现servlet3.0无web.xml 配置servlet对象的
    springmvc学习指南 之---第26篇 在idea中如何debug跟踪到tomcat内部代码
  • 原文地址:https://www.cnblogs.com/robothy/p/14566474.html
Copyright © 2011-2022 走看看