Maven BOM!拿來吧你

「本文已參與好文召集令活動,點擊查看:後端、大前端雙賽道投稿,2萬元獎池等你挑戰!前端

what BOM?

BOM(Bill of Materials)是由Maven提供的功能,它經過定義一整套相互兼容的jar包版本集合,java

使用時只須要依賴該BOM文件,便可放心的使用須要的依賴jar包,且無需再指定版本號web

BOM的維護方負責版本升級,並保證BOM中定義的jar包版本之間的兼容性。spring

why BOM?

使用BOM除了能夠方便使用者在聲明依賴的客戶端時不須要指定版本號外,後端

最主要的緣由是能夠解決依賴衝突,如考慮如下的依賴場景:markdown

項目A依賴項目B 2.1和項目C 1.2版本:框架

項目B 2.1依賴項目D 1.1版本;maven

項目C 1.2依賴項目D 1.3版本;spring-boot

在該例中,項目A對於項目D的依賴就會出現衝突,按照maven dependency mediation的規則,最後生效的多是:項目A中會依賴到項目D1.1版本(就近原則,取決於路徑和依賴的前後,和Maven版本有關係)。oop

在這種狀況下,因爲項目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版本爲例,使用官方推薦的版本組合比較穩定,通常不會有什麼大的問題

image.png

<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管理,拿來吧你!!!

參考:howtodoinjava.com/maven/maven…

相關文章
相關標籤/搜索