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

深入學(xué)習(xí)Java中的SPI機(jī)制

 更新時(shí)間:2019年09月03日 10:33:04   作者:技術(shù)-劉騰飛  
這篇文章主要介紹了深入學(xué)習(xí)Java中的SPI機(jī)制,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

概述

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

Java中SPI機(jī)制主要思想是將裝配的控制權(quán)移到程序之外,在模塊化設(shè)計(jì)中這個(gè)機(jī)制尤其重要,其核心思想就是解耦。

SPI整體機(jī)制圖如下

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

java.util.ServiceLoader

首先,ServiceLoader實(shí)現(xiàn)了Iterable接口,所以它有迭代器的屬性,這里主要都是實(shí)現(xiàn)了迭代器的hasNext和next方法。這里主要都是調(diào)用的lookupIterator的相應(yīng)hasNext和next方法,lookupIterator是懶加載迭代器。

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

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

demo

//定義一個(gè)接口HelloSPI。
package com.vivo.study.spidemo.spi;
public interface HelloSPI {
  void sayHello();
}
//完成接口的多個(gè)實(shí)現(xiàn)。
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/目錄里創(chuàng)建一個(gè)以com.vivo.study.spidemo.spi.HelloSPI的文件,這個(gè)文件里的內(nèi)容就是這個(gè)接口的具體的實(shí)現(xiàn)類。
內(nèi)容如下
com.vivo.study.spidemo.spi.impl.ImageHello
com.vivo.study.spidemo.spi.impl.TextHello
// 使用 ServiceLoader 來加載配置文件中指定的實(shí)現(xiàn)
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);
    // 執(zhí)行不同廠商的業(yè)務(wù)實(shí)現(xiàn),具體根據(jù)業(yè)務(wù)需求配置
    for (HelloSPI helloSPI : serviceLoader) {
      helloSPI.sayHello();
    }
  }
}
//輸出結(jié)果如下:
Image Hello
Text Hello

不足

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

2.獲取某個(gè)實(shí)現(xiàn)類的方式不夠靈活,只能通過 Iterator 形式獲取,不能根據(jù)某個(gè)參數(shù)來獲取對(duì)應(yīng)的實(shí)現(xiàn)類。

3.多個(gè)并發(fā)多線程使用 ServiceLoader 類的實(shí)例是不安全的。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java實(shí)現(xiàn)線性表的順序存儲(chǔ)

    Java實(shí)現(xiàn)線性表的順序存儲(chǔ)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)線性表的順序存儲(chǔ),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • Java中如何將符號(hào)分隔的文本文件txt轉(zhuǎn)換為excel

    Java中如何將符號(hào)分隔的文本文件txt轉(zhuǎn)換為excel

    這篇文章主要介紹了Java中如何將符號(hào)分隔的文本文件txt轉(zhuǎn)換為excel,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • SpringBoot 使用Prometheus采集自定義指標(biāo)數(shù)據(jù)的方案

    SpringBoot 使用Prometheus采集自定義指標(biāo)數(shù)據(jù)的方案

    這篇文章主要介紹了SpringBoot 使用Prometheus采集自定義指標(biāo)數(shù)據(jù),我們在k8s集群成功搭建了Prometheus服務(wù),今天,我們將在springboot2.x中使用prometheus記錄指標(biāo),需要的朋友可以參考下
    2022-10-10
  • springboot中的Application.properties常用配置

    springboot中的Application.properties常用配置

    這篇文章主要介紹了springboot中的Application.properties常用配置,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Java用正則表達(dá)式實(shí)現(xiàn)${name}形式的字符串模板實(shí)例

    Java用正則表達(dá)式實(shí)現(xiàn)${name}形式的字符串模板實(shí)例

    這篇文章主要給大家介紹了Java如何用正則表達(dá)式實(shí)現(xiàn)${name}形式的字符串模板,文章給出詳細(xì)的實(shí)例代碼,對(duì)大家的理解和學(xué)習(xí)會(huì)很有幫助,有需要的朋友們下面來一起看看吧。
    2016-12-12
  • java 數(shù)組轉(zhuǎn)list的兩種方式

    java 數(shù)組轉(zhuǎn)list的兩種方式

    這篇文章主要介紹了java 數(shù)組轉(zhuǎn)list的兩種方式,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-10-10
  • 淺談mybatis如何半自動(dòng)化解耦(推薦)

    淺談mybatis如何半自動(dòng)化解耦(推薦)

    這篇文章主要介紹了淺談mybatis如何半自動(dòng)化解耦,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Sentinel熔斷規(guī)則原理示例詳解分析

    Sentinel熔斷規(guī)則原理示例詳解分析

    這篇文章主要介紹了Sentinel熔斷規(guī)則,采用了示例代碼的方式對(duì)Sentinel熔斷規(guī)則進(jìn)行了詳細(xì)的分析,以便廣大讀者朋友們更易理解,有需要的朋友可以參考下
    2021-09-09
  • Java動(dòng)態(tài)添加view的方法

    Java動(dòng)態(tài)添加view的方法

    這篇文章主要介紹了Java動(dòng)態(tài)添加view的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-01-01
  • 解決運(yùn)行jar包出錯(cuò):ClassNotFoundException問題

    解決運(yùn)行jar包出錯(cuò):ClassNotFoundException問題

    這篇文章主要介紹了解決運(yùn)行jar包出錯(cuò):ClassNotFoundException問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12

最新評(píng)論