欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java的SPI機制以及基于SPI編程示例詳解

 更新時間:2023年08月25日 11:15:37   作者:jacheut  
這篇文章主要為大家介紹了Java的SPI機制以及基于SPI編程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

背景

在面向對象的設計原則中,一般推薦模塊之間基于接口編程,通常情況下調用方模塊是不會感知到被調用方模塊的內部具體實現。一旦代碼里面涉及具體實現類,就違反了開閉原則。如果需要替換一種實現,就需要修改代碼。

為了實現在模塊裝配的時候不用在程序里面動態(tài)指明,這就需要一種服務發(fā)現機制。Java SPI 就是提供了這樣一個機制:為某個接口尋找服務實現的機制。這有點類似 IOC 的思想,將裝配的控制權移交到了程序之外。

SPI 英文為 Service Provider Interface, 字面意思就是:“服務提供者的接口”,可以理解為專門提供給服務調用者或者擴展框架功能的開發(fā)者去使用的一個接口。

SPI 將服務接口和具體的服務實現分離開來,將服務調用方和服務實現者解耦,能夠提升程序的擴展性、可維護性。修改或者替換服務實現并不需要修改調用方。

使用場景

很多框架都使用了 Java 的 SPI 機制,比如:數據庫加載驅動,日志接口,以及 dubbo 的擴展實現等等。拿日志接口來說,Spring框架提供的日志服務 SLF4J 其實只是一個日志接口,但是 SLF4J 的具體實現可以有幾種,比如:Logback、Log4j、Log4j2 等等,而且還可以切換,在切換日志具體實現的時候我們是不需要更改項目代碼的,只需要在 Maven 依賴里面修改一些 pom 依賴就好了。

與API的區(qū)別

API:是指可以用來完成某項功能的類、接口或者方法。提供方提供實現方式,調用方只需調用即可。

SPI:是指用來繼承、擴展,完成自定義功能的類、接口或者方法。調用方可選擇使用提供方提供的內置實現,也可以自己實現。

SPI原理

Java SPI的具體約定為:當服務的提供者提供了服務接口后,在jar包的META-INF/services目錄下同時創(chuàng)建一個以服務接口全類名命名的文件,該文件的內容就是實現該服務接口具體實現類的全名,當然這個服務接口實現類也必須在這個jar中。當外部程序裝配這個模塊的時候,就能通過該jar包META-INF/services下的配置文件找到具體的實現類,并裝載實例化,完成模塊的注入。Java就是通過掃描META-INF/services文件夾目錄下面的文件,把實現類加載到servciceLoader里面。

簡單來講,META-INF/services/下的配置文件名字就是接口的全類名,實現類的全類名就是問這個文件的內容,如果有多個

實現類,可以全部寫在這個文件中,同時在實現類中要實現這個接口。

不定義在META-INF/services下面行不行?就想定義在別的地方可以嗎?

答案是不行。看下圖JDK源碼中,因為已經定義為配置路徑,如果寫在別的地方,類加載器就會找不到了。

案例實現

代碼結構如下:

├─main
│ ├─java
│ │ └─com
│ │ ├─test
│ │ │ └─Apple
│ │ │ └─Fruit
│ └─resources
│ ├─META-INF
│ │ └─services
│ │ └─com.test.Fruit

  • 創(chuàng)建接口Fruit,模擬服務提供方接口
package com.test;
public interface Fruit {
}
  • 創(chuàng)建接口實現類Apple,實現Fruit接口;
package com.test;
public class Apple implements Fruit {
    static {
        System.out.println("hi,I am an apple!");
    }
}
  • 在resources結構下創(chuàng)建META-INF/services目錄,在這個目錄下,創(chuàng)建以這個接口名命名的文件com.test.Fruit,同時在這個文件中寫入這個實現類的全類名;
com.test.Apple
  • 創(chuàng)建Test測試類,在測試類中創(chuàng)建一個類加載器ServiceLoader來實現本案例。
import com.test.Fruit;
import java.util.ServiceLoader;
public class Test {
    public static void main(String[] args) {
        ServiceLoader<Fruit> test = ServiceLoader.load(Fruit.class);
        for (Fruit item:test){
        }
    }
}

執(zhí)行結果如下,表明本案例成功執(zhí)行。

hi,I am an apple!

以上就是Java的SPI機制以及基于SPI編程示例詳解的詳細內容,更多關于Java SPI機制的資料請關注腳本之家其它相關文章!

相關文章

  • Java8生成時間方式及格式化時間的方法實例

    Java8生成時間方式及格式化時間的方法實例

    這篇文章主要給大家介紹了關于Java8生成時間方式及格式化時間的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • Java面試崗常見問題之ArrayList和LinkedList的區(qū)別

    Java面試崗常見問題之ArrayList和LinkedList的區(qū)別

    ArrayList和LinkedList作為我們Java中最常使用的集合類,很多人在被問到他們的區(qū)別時,憋了半天僅僅冒出一句:一個是數組一個是鏈表。這樣回答簡直讓面試官吐血。為了讓兄弟們打好基礎,我們通過實際的使用測試,好好說一下ArrayList和LinkedList的區(qū)別這道經典的面試題
    2022-01-01
  • Spring中OpenFeign的使用方法最佳實踐

    Spring中OpenFeign的使用方法最佳實踐

    這篇文章主要介紹了Spring中OpenFeign使用的相關資料,OpenFeign是一個聲明式的WebService客戶端,簡化了微服務之間的調用,類似于Controller調用Service,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-02-02
  • springboot+vue項目從第一行代碼到上線部署全流程

    springboot+vue項目從第一行代碼到上線部署全流程

    本文詳細介紹了如何從零開始搭建一個基于Spring Boot和Vue.js的前后端分離項目,并涵蓋項目需求分析、技術選型、項目結構設計、前后端交互、部署上線等全過程,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • MyBatisPlus 主鍵策略的實現(4種)

    MyBatisPlus 主鍵策略的實現(4種)

    MyBatis Plus 集成了多種主鍵策略,幫助用戶快速生成主鍵,本文主要介紹了MyBatisPlus主鍵策略的實現,具有一定的參考價值,感興趣的可以了解一下
    2023-10-10
  • 利用session實現簡單購物車功能

    利用session實現簡單購物車功能

    這篇文章主要為大家詳細介紹了利用session實現簡單購物車功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Java實現十秒向MySQL插入百萬條數據

    Java實現十秒向MySQL插入百萬條數據

    這篇文章主要為大家詳細介紹了Java如何實現十秒向MySQL插入百萬條數據,文中的示例代碼講解詳細,對我們學習或工作有一定借鑒價值,需要的可以參考一下
    2022-11-11
  • 為什么Java開發(fā)需要配置環(huán)境變量

    為什么Java開發(fā)需要配置環(huán)境變量

    這篇文章主要介紹了為什么Java開發(fā)需要配置環(huán)境變量,幫助大家更好的理解和學習Java,感興趣的朋友可以了解下
    2020-08-08
  • Java?空和null的區(qū)別

    Java?空和null的區(qū)別

    本文主要介紹了Java?空和null的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-04-04
  • SpringBoot?MongoCustomConversions自定義轉換方式

    SpringBoot?MongoCustomConversions自定義轉換方式

    這篇文章主要介紹了SpringBoot?MongoCustomConversions自定義轉換方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08

最新評論