最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中的SPI機(jī)制使用解析

 更新時(shí)間:2023年10月07日 08:57:05   作者:cloneme01  
這篇文章主要介紹了Java中的SPI機(jī)制使用解析,SPI意思是"服務(wù)提供者的接口",專門提供給服務(wù)提供者或者擴(kuò)展框架功能的開發(fā)者去使用的接口,SPI 將服務(wù)接口和服務(wù)實(shí)現(xiàn)分離開來,將服務(wù)調(diào)用方和服務(wù)實(shí)現(xiàn)方進(jìn)行解耦,需要的朋友可以參考下

SPI機(jī)制簡(jiǎn)述

SPI(Service Provider Interface的縮寫) 意思是:“服務(wù)提供者的接口”,專門提供給服務(wù)提供者或者擴(kuò)展框架功能的開發(fā)者去使用的接口。SPI 將服務(wù)接口和服務(wù)實(shí)現(xiàn)分離開來,將服務(wù)調(diào)用方和服務(wù)實(shí)現(xiàn)方進(jìn)行解耦,能夠提升程序的擴(kuò)展性和可維護(hù)性,當(dāng)修改或替換服務(wù)實(shí)現(xiàn)并不需要修改調(diào)用方。 SPI 是JDK內(nèi)置的一種動(dòng)態(tài)加載擴(kuò)展點(diǎn)的實(shí)現(xiàn)。

場(chǎng)景

很多框架都使用了JAVA 的 SPI 機(jī)制,如:數(shù)據(jù)庫加載驅(qū)動(dòng)、日志接口以及DUBBO的擴(kuò)展實(shí)現(xiàn)等。

SPI與API的區(qū)別

(1)API(Application Programming Interface的縮寫),一般都是由實(shí)現(xiàn)方制定接口并完成對(duì)接口的實(shí)現(xiàn),調(diào)用方僅依賴接口調(diào)用,并無法選擇不同實(shí)現(xiàn)。

(2)SPI(Service Provider Interface的縮寫),一般都是由調(diào)用方來制定接口規(guī)范,將接口規(guī)范提供給外部廠商來實(shí)現(xiàn),調(diào)用方在調(diào)用時(shí)可以選擇不同的實(shí)現(xiàn)。

在這里插入圖片描述

SPI的實(shí)現(xiàn)

(1)定義一個(gè)公共接口(一般定義在一個(gè)公共的模塊中,實(shí)現(xiàn)方和調(diào)用方都會(huì)引用該模塊);

(2)實(shí)現(xiàn)方需要實(shí)現(xiàn)剛剛定義的公共接口;

(3)實(shí)現(xiàn)方在“META-INF/services”目錄下新建一個(gè)名稱為接口的全限定名的文本文件,文件內(nèi)容為接口實(shí)現(xiàn)類的全限定名(一般會(huì)在resources目錄下創(chuàng)建如上文件);

(4)調(diào)用方通過ServiceLoader#load方法加載接口的實(shí)現(xiàn)類實(shí)例。

SPI的示例代碼

在“模塊1”中定義一個(gè)公共接口“Hello”,分別在“模塊2”和“模塊2”兩個(gè)模塊中實(shí)現(xiàn)剛剛定義的接口作為兩個(gè)實(shí)現(xiàn)方,在“模塊4”中通過ServiceLoader進(jìn)行測(cè)試并作為調(diào)用方。

// 1. 公共接口(模塊1):
package com.hadoopx.common.util;
public interface Hello {
    void say();
}
// 2. 具體實(shí)現(xiàn)1(模塊2):
package com.hadoopx.m1.test;
import com.hadoopx.common.util.Hello;
public class Chinese implements Hello {
    @Override
    public void say() {
        System.out.println("你好!");
    }
}
// 3. 創(chuàng)建文件: resources/META-INF/services/com.hadoopx.common.util.Hello,內(nèi)容如下:
com.hadoopx.m1.test.Chinese
// 4. 具體實(shí)現(xiàn)2(模塊3):
package com.hadoopx.m2.test;
import com.hadoopx.common.util.Hello;
public class English implements Hello {
    @Override
    public void say() {
        System.out.println("HELLO WORLD!");
    }
}
// 5. 創(chuàng)建文件: resources/META-INF/services/com.hadoopx.common.util.Hello,內(nèi)容如下:
com.hadoopx.m2.test.English
// 6. 調(diào)用方(模塊4):
package com.hadoopx.test;
import com.hadoopx.common.util.Hello;
import java.util.Iterator;
import java.util.ServiceLoader;
public class Test {
    public static void main(String[] args) {
        ServiceLoader<Hello> loader = ServiceLoader.load(Hello.class);
        Iterator<Hello> iterator = loader.iterator();
        while (iterator.hasNext()) {
            Hello hello = iterator.next();
            hello.say();
        }
    }
}

JAVA與SPRING關(guān)于SPI的區(qū)別

SPRING SPI對(duì)JAVA SPI進(jìn)行了封裝和增強(qiáng),調(diào)用方可以使用SpringFactoriesLoader.loadFactories方法得到配置文件中寫的實(shí)現(xiàn)類的集合,其要求如下:

(1)配置文件必須在resources/META-INF/目錄下,文件名必須為spring.factories;

(2)文件內(nèi)容為鍵值對(duì)形式,一個(gè)鍵可以有多個(gè)值(需要用逗號(hào)分割),鍵值都要求是類的全限定名,鍵名為接口的全限定名。

在SPRING BOOT的自動(dòng)裝配過程中,最終會(huì)加載META-INF/spring.factories文件,加載的過程是由SpringFactoriesLoader加載的,它會(huì)從CLASSPATH下的每個(gè)JAR包中搜尋所有META-INF/spring.factories配置文件并解析,然后將其中定義的BEAN注入到SPRING容器。

// 1. 公共接口(模塊1):
package com.hadoopx.common.util;
public interface Hello {
    void say();
}
// 2. 具體實(shí)現(xiàn)1(模塊2):
package com.hadoopx.m1.test;
import com.hadoopx.common.util.Hello;
public class Chinese implements Hello {
    @Override
    public void say() {
        System.out.println("你好!");
    }
}
// 3. 創(chuàng)建/修改文件: resources/META-INF/spring.factories,內(nèi)容如下:
com.hadoopx.common.util.Hello = \
com.hadoopx.m1.test.Chinese
// 4. 具體實(shí)現(xiàn)2(模塊3):
package com.hadoopx.m2.test;
import com.hadoopx.common.util.Hello;
public class English implements Hello {
    @Override
    public void say() {
        System.out.println("HELLO WORLD!");
    }
}
// 5. 創(chuàng)建/修改文件: resources/META-INF/spring.factories,內(nèi)容如下:
com.hadoopx.common.util.Hello = \
com.hadoopx.m2.test.English
// 6. 調(diào)用方(模塊4):
package com.hadoopx.test;
import com.hadoopx.common.util.Hello;
import java.util.Iterator;
import java.util.ServiceLoader;
public class Test {
    public static void main(String[] args) {
        List<Hello> hellos = SpringFactoriesLoader.loadFactories(Hello.class, null);
        for(Hello hello: hellos) {
            hello.say();
        };
    }
}

SPI的缺點(diǎn)

(1)ServiceLoader會(huì)遍歷加載所有的實(shí)現(xiàn)類,效率相對(duì)較低;

(2)當(dāng)由多個(gè)ServiceLoader同時(shí)加載時(shí),會(huì)存在并發(fā)的問題。

到此這篇關(guān)于Java中的SPI機(jī)制使用解析的文章就介紹到這了,更多相關(guān)SPI機(jī)制使用詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于@JsonSerialize和@JsonInclude注解使用方法

    基于@JsonSerialize和@JsonInclude注解使用方法

    這篇文章主要介紹了@JsonSerialize和@JsonInclude注解使用方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Spring整合Dubbo框架過程及原理解析

    Spring整合Dubbo框架過程及原理解析

    這篇文章主要介紹了Spring整合Dubbo框架過程及原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • springboot捕獲全局異常實(shí)現(xiàn)過程

    springboot捕獲全局異常實(shí)現(xiàn)過程

    本文主要介紹了Java中的異常和錯(cuò)誤,包括Exception和Error的區(qū)別、如何捕捉全局異常、自定義異常的實(shí)現(xiàn)等,通過實(shí)例代碼和步驟,展示了如何在Spring?Boot項(xiàng)目中實(shí)現(xiàn)全局異常處理,并自定義異常類來增強(qiáng)程序的健壯性
    2026-03-03
  • 使用MyBatis 動(dòng)態(tài)update數(shù)據(jù)

    使用MyBatis 動(dòng)態(tài)update數(shù)據(jù)

    使用mybatis寫sql,需要?jiǎng)討B(tài)更新對(duì)象數(shù)據(jù),每次需要更新的字段不同,為了防止null空異常,就需要用動(dòng)態(tài)sql了,下面給大家分享一段代碼關(guān)于mybatis動(dòng)態(tài)update,需要的朋友參考下
    2016-11-11
  • Java中過濾器和攔截器的區(qū)別有哪些

    Java中過濾器和攔截器的區(qū)別有哪些

    過濾器和攔截器非常相似,但是它們有很大的區(qū)別,這篇文章主要介紹了Java中過濾器和攔截器的區(qū)別有哪些的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考下
    2025-09-09
  • java判斷一個(gè)文件是否為二進(jìn)制文件的方法

    java判斷一個(gè)文件是否為二進(jìn)制文件的方法

    這篇文章主要介紹了java判斷一個(gè)文件是否為二進(jìn)制文件的方法,涉及java針對(duì)文件的讀取及編碼判斷技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • java org.springframework.boot 對(duì)redis操作方法

    java org.springframework.boot 對(duì)redis操作方法

    在Spring Boot項(xiàng)目中操作Redis,你可以使用Spring Data Redis,Spring Data Redis是Spring提供的一個(gè)用于簡(jiǎn)化Redis數(shù)據(jù)訪問的模塊,它提供了一個(gè)易于使用的編程模型來與Redis交互,本文給大家介紹java org.springframework.boot 對(duì)redis操作方法,感興趣的朋友一起看看吧
    2025-04-04
  • 淺談SpringBoot自動(dòng)配置的坑

    淺談SpringBoot自動(dòng)配置的坑

    SpringBoot的自動(dòng)配置簡(jiǎn)化了開發(fā),但也會(huì)帶來一些問題,本文通過幾個(gè)實(shí)際案例探討了一些自動(dòng)配置可能帶來的問題,下面就來詳細(xì)的介紹下
    2026-05-05
  • redisson常用加鎖方式詳解

    redisson常用加鎖方式詳解

    文章介紹了兩種Redisson加鎖方式的區(qū)別:基本的RLock方式和使用RedissonDistributedLocker的tryLock方式,RLock需要手動(dòng)處理鎖的等待和持有時(shí)間,而tryLock則提供了更高層次的封裝,簡(jiǎn)化了鎖的操作,并且在超時(shí)后會(huì)自動(dòng)返回或釋放鎖
    2026-01-01
  • Java微信授權(quán)登陸的實(shí)現(xiàn)示例

    Java微信授權(quán)登陸的實(shí)現(xiàn)示例

    微信授權(quán)登錄,官方文檔寫的比較簡(jiǎn)潔。所以對(duì)于會(huì)的人一目了然,而對(duì)于新手剛?cè)腴T的人來說是舉步維艱。本文詳細(xì)的介紹了Java微信授權(quán)登陸的實(shí)現(xiàn)示例,感興趣的朋友可以了解一下
    2021-06-06

最新評(píng)論

兴安县| 哈尔滨市| 道孚县| 河池市| 象州县| 横峰县| 林甸县| 东方市| 滕州市| 邹平县| 元朗区| 大安市| 会东县| 庆安县| 蒙自县| 蕲春县| 固原市| 侯马市| 紫阳县| 阿合奇县| 丰台区| 金川县| 四平市| 上饶县| 太原市| 定日县| 耿马| 改则县| 金山区| 通河县| 武清区| 贺州市| 榕江县| 昌乐县| 玛纳斯县| 柳河县| 清远市| 安义县| 柳江县| 延吉市| 施甸县|