亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

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

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

楚雄市| 高邮市| 布尔津县| 五河县| 嘉定区| 河津市| 平遥县| 共和县| 永顺县| 大港区| 广元市| 宁海县| 梅州市| 额济纳旗| 来宾市| 哈巴河县| 大宁县| 苏尼特左旗| 社旗县| 永川市| 丹凤县| 祁东县| 肇州县| 霍山县| 收藏| 高台县| 枝江市| 临安市| 读书| 安西县| 崇义县| 沧州市| 陕西省| 登封市| 海宁市| 蒙自县| 富裕县| 保康县| 定结县| 隆尧县| 南靖县|