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

Java中的SPI機制使用解析

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

SPI機制簡述

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

場景

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

SPI與API的區(qū)別

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

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

在這里插入圖片描述

SPI的實現(xiàn)

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

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

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

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

SPI的示例代碼

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

// 1. 公共接口(模塊1):
package com.hadoopx.common.util;
public interface Hello {
    void say();
}
// 2. 具體實現(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. 具體實現(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對JAVA SPI進行了封裝和增強,調(diào)用方可以使用SpringFactoriesLoader.loadFactories方法得到配置文件中寫的實現(xiàn)類的集合,其要求如下:

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

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

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

// 1. 公共接口(模塊1):
package com.hadoopx.common.util;
public interface Hello {
    void say();
}
// 2. 具體實現(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. 具體實現(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的缺點

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

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

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

    java判斷一個文件是否為二進制文件的方法

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

    java org.springframework.boot 對redis操作方法

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

    淺談SpringBoot自動配置的坑

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

    redisson常用加鎖方式詳解

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

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

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

最新評論

东丰县| 改则县| 南城县| 涪陵区| 哈密市| 大名县| 永安市| 宁南县| 许昌县| 南丰县| 乌拉特前旗| 怀远县| 马鞍山市| 阳春市| 苍溪县| 东兰县| 焦作市| 连云港市| 烟台市| 德令哈市| 扬中市| 万山特区| 类乌齐县| 佛教| 米泉市| 南澳县| 和田县| 普安县| 安乡县| 临沂市| 古丈县| 怀化市| 林州市| 黄石市| 新乐市| 方山县| 丽江市| 桐庐县| 山阳县| 江北区| 乾安县|