中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中SPI機制的原理是什么

發布時間:2021-01-16 10:33:37 來源:億速云 閱讀:181 作者:Leah 欄目:編程語言

這期內容當中小編將會給大家帶來有關Java中SPI機制的原理是什么,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

概述

SPI(Service Provider Interface),是JDK內置的一種服務提供發現機制,可以用來啟用框架擴展和替換組件,主要是被框架的開發人員使用,比如java.sql.Driver接口,其他不同廠商可以針對同一接口做出不同的實現,MySQL和PostgreSQL都有不同的實現提供給用戶,而Java的SPI機制可以為某個接口尋找服務實現。

Java中SPI機制主要思想是將裝配的控制權移到程序之外,在模塊化設計中這個機制尤其重要,其核心思想就是解耦。

SPI整體機制圖如下

Java中SPI機制的原理是什么

當服務的提供者提供了一種接口的實現之后,需要在classpath下的META-INF/services/目錄里創建一個以服務接口命名的文件,這個文件里的內容就是這個接口的具體的實現類。當其他的程序需要這個服務的時候,就可以通過查找這個jar包(一般都是以jar包做依賴)的META-INF/services/中的配置文件,配置文件中有接口的具體實現類名,可以根據這個類名進行加載實例化,就可以使用該服務了。JDK中查找服務的實現的工具類是:java.util.ServiceLoader。

java.util.ServiceLoader

首先,ServiceLoader實現了Iterable接口,所以它有迭代器的屬性,這里主要都是實現了迭代器的hasNext和next方法。這里主要都是調用的lookupIterator的相應hasNext和next方法,lookupIterator是懶加載迭代器。

其次,LazyIterator中的hasNext方法,靜態變量PREFIX就是”META-INF/services/”目錄,這也就是為什么需要在classpath下的META-INF/services/目錄里創建一個以服務接口命名的文件。

最后,通過反射方法Class.forName()加載類對象,并用newInstance方法將類實例化,并把實例化后的類緩存到providers對象中,(LinkedHashMap<String,S>類型) 然后返回實例對象。

demo

//定義一個接口HelloSPI。
package com.vivo.study.spidemo.spi;
public interface HelloSPI {
  void sayHello();
}
//完成接口的多個實現。
package com.vivo.study.spidemo.spi.impl;
import com.vivo.study.spidemo.spi.HelloSPI;
public class ImageHello implements HelloSPI {
  public void sayHello() {
    System.out.println("Image Hello");
  }
}
package com.vivo.study.spidemo.spi.impl;
import com.vivo.study.spidemo.spi.HelloSPI;
public class TextHello implements HelloSPI {
  public void sayHello() {
    System.out.println("Text Hello");
  }
}
//在META-INF/services/目錄里創建一個以com.vivo.study.spidemo.spi.HelloSPI的文件,這個文件里的內容就是這個接口的具體的實現類。
內容如下
com.vivo.study.spidemo.spi.impl.ImageHello
com.vivo.study.spidemo.spi.impl.TextHello
// 使用 ServiceLoader 來加載配置文件中指定的實現
package com.vivo.study.spidemo.test
import java.util.ServiceLoader;
import com.vivo.study.spidemo.spi.HelloSPI;
public class SPIDemo {
  public static void main(String[] args) {
    ServiceLoader<HelloSPI> serviceLoader = ServiceLoader.load(HelloSPI.class);
    // 執行不同廠商的業務實現,具體根據業務需求配置
    for (HelloSPI helloSPI : serviceLoader) {
      helloSPI.sayHello();
    }
  }
}
//輸出結果如下:
Image Hello
Text Hello

不足

1.不能按需加載,需要遍歷所有的實現,并實例化,然后在循環中才能找到我們需要的實現。如果不想用某些實現類,或者某些類實例化很耗時,它也被載入并實例化了,這就造成了浪費。

2.獲取某個實現類的方式不夠靈活,只能通過 Iterator 形式獲取,不能根據某個參數來獲取對應的實現類。

3.多個并發多線程使用 ServiceLoader 類的實例是不安全的。

上述就是小編為大家分享的Java中SPI機制的原理是什么了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

富宁县| 肥西县| 正宁县| 清苑县| 衡南县| 阜康市| 马尔康县| 沐川县| 新巴尔虎右旗| 界首市| 兴安盟| 多伦县| 法库县| 斗六市| 苍梧县| 临高县| 莱芜市| 龙川县| 黑河市| 汕头市| 利川市| 嘉义县| 奎屯市| 盐津县| 洪湖市| 信宜市| 东山县| 吴堡县| 寻甸| 海伦市| 龙井市| 玉门市| 泾川县| 含山县| 新龙县| 墨江| 唐山市| 五大连池市| 乐昌市| 盱眙县| 磴口县|