乐趣区

关于java:Maven-BOM拿来吧你

what BOM?

BOM(Bill of Materials)是由 Maven 提供的性能, 它通过定义一 整套互相兼容 的 jar 包版本汇合,

应用时只须要依赖该 BOM 文件,即可释怀的应用须要的依赖 jar 包,且 无需再指定版本号

BOM 的 保护方负责版本升级,并保障 BOM 中定义的 jar 包版本之间的兼容性。

why BOM?

应用 BOM 除了能够不便使用者在申明依赖的客户端时 不须要指定版本号 外,

最次要的起因是能够 解决依赖抵触,如思考以下的依赖场景:

我的项目 A 依赖我的项目 B 2.1 和我的项目 C 1.2 版本:

我的项目 B 2.1 依赖我的项目 D 1.1 版本;

我的项目 C 1.2 依赖我的项目 D 1.3 版本;

在该例中,我的项目 A 对于我的项目 D 的依赖就会呈现抵触,依照 maven dependency mediation 的规定,最初失效的可能是: 我的项目 A 中会依赖到我的项目 D1.1 版本(就近准则,取决于门路和依赖的先后, 和 Maven 版本有关系)。

在这种状况下,因为我的项目 C 依赖 1.3 版本的我的项目 D,然而在运行时失效确实是 1.1 版本,

所以在运行时很容易产生问题,如 NoSuchMethodError, ClassNotFoundException等,

有些 jar 包抵触定位还是比拟难的,这种形式能够节俭很多定位此类问题的工夫。

Spring、SpringBoot、SpringCloud本身都采纳了此机制来解决第三方包的抵触,

常见官网提供的 BOM:

1) RESTEasy Maven BOM dependency

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-bom</artifactId>
            <version>3.0.6.Final</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

2. JBOSS Maven BOM dependency

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.jboss.bom</groupId>
            <artifactId>jboss-javaee-6.0-with-tools</artifactId>
            <version>${some.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement> 

3) Spring Maven BOM dependency

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-framework-bom</artifactId>
            <version>4.0.1.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

4) Jersey Maven BOM dependency

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.glassfish.jersey</groupId>
            <artifactId>jersey-bom</artifactId>
            <version>${jersey.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

5) SpringCloud SpringBoot Maven BOM dependency

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.4.4</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2020.0.2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

看着有点蒙不要紧,上面会具体介绍这些配置的作用

本人开发的我的项目中也倡议应用此优良传统, 尤其切实我的项目开发初期,在前期再批改成 BOM 可能波及很多版本的批改,就比拟难了。

how BOM?

定义 BOM

BOM 实质上是一个一般的 POM 文件,区别是对于 应用方 而言,失效的只有 <dependencyManagement>这一个局部。

只须要在 <dependencyManagement> 定义对外公布的客户端版本即可,

比方须要在我的项目中 对立 所有 SpringBoot 和 SpringCloud 的 版本

第一步须要在 POM 文件中减少两个的官网 BOM,以目前最新稳固的 SpringBoot 版本为例,应用官网举荐的版本组合比较稳定,个别不会有什么大的问题

<groupId>com.niu.not</groupId>
<artifactId>niu-dependency</artifactId>
<version>1.1.1</version>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.4.6</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2020.0.3</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.6</version>
    </dependency>
</dependencies>

上面的 Gson 是除了 SpringBoot 和 SpingCloud 外须要对立版本的 jar

其余工程应用办法

在我的项目主 pom.xml 文件中 <dependencyManagement></dependencyManagement> 节点下退出 BOM 的 GAV 信息如下:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.niu.not</groupId>
            <artifactId>niu-dependency</artifactId>
            <version>1.1.1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

在须要应用相干 JAR 包的 pom.xml 文件中 <dependencies></dependencies> 节点下引入如下:

<dependencies>
    <!-- 此时用到 Spring 和 Gson 都不须要加版本号, 会主动援用 BOM 中提供的版本 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
    </dependency>
</dependencies>

这种设置后,如果我的项目要求降级 Spring 版本,只须要在提供方降级验证兼容性,而后批改 BOM 依赖即可

如果须要应用不同于以后 bom 中所保护的 jar 包版本,则加上 <version> 笼罩即可,如:

<dependencies>
    <!-- 此时用到 Spring 和 Gson 都不须要加版本号, 会主动援用 BOM 中提供的版本 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <!-- 会笼罩掉 BOM 中申明的版本 2.8.6,应用自定义版本 2.8.2-->
        <version>2.8.2</version>
    </dependency>
</dependencies>

小结

Jar 包抵触十分烦人,Spring 框架相干的抵触,有些报错十分不清晰或者基本不报错间接进行服务,

这种问题很难定位,开发人员应该聚焦业务开发,不应该在这下面节约过多工夫,

所以对立的版本治理还是十分有用的,不然 Spring 的牛逼框架为啥都在用呢,

BOM 治理,拿来吧你!!!

参考:https://howtodoinjava.com/mav…

退出移动版