国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

什么是 SPI,和API有什么區(qū)別?

這篇具有很好參考價(jià)值的文章主要介紹了什么是 SPI,和API有什么區(qū)別?。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

面試回答

Java 中區(qū)分 API 和 SPI,通俗的講:API 和 SPI 都是相對(duì)的概念,他們的差別只在語義上,API 直接被應(yīng)用開發(fā)人員使用,SPI 被框架擴(kuò)展人員使用。

API Application Programming Interface

大多數(shù)情況下,都是實(shí)現(xiàn)方來制定接口并完成對(duì)接口的不同實(shí)現(xiàn),調(diào)用方僅僅依賴卻無權(quán)選擇不同實(shí)現(xiàn)。

SPI Service Provider Interface

而如果是調(diào)用方來制定接口,實(shí)現(xiàn)方來針對(duì)接口實(shí)現(xiàn)不同的實(shí)現(xiàn)。調(diào)用方來選擇自己需要的實(shí)現(xiàn)方。

知識(shí)擴(kuò)展

如何定義一個(gè) SPI

步驟1、定義一組接口(假設(shè)是 com.chiyi.test.IShout),并寫出接口的一個(gè)或多個(gè)實(shí)現(xiàn),(假設(shè)是 com.chiyi.test.Dog、com.chiyi.test.Cat)。

public interface IShout {
    void shout();
}
public class Dog implements IShout{
    @Override
    public void shout() {
        System.out.println("wang wang");
    }
}
public class Cat implements IShout{
    @Override
    public void shout() {
        System.out.println("miao miao");
    }
}

步驟2、在 src/main/resources/ 下建立 /META-INF/services目錄,新增一個(gè)以接口命名的文件(com.chiyi.test.IShout 文件),內(nèi)容是要應(yīng)用的實(shí)現(xiàn)類(這里是 com.chiyi.test.Dogcom.chiyi.test.Cat,每行一個(gè)類)。

com.chiyi.test.Dog
com.chiyi.test.Cat

步驟3、使用 ServiceLoader 來加載配置文件中指定的實(shí)現(xiàn)。

public class Main {


    public static void main(String[] args) {
        ServiceLoader<IShout> shouts=ServiceLoader.load(IShout.class);
        for(IShout s:shouts){
            s.shout();
        }
    }
}

代碼輸出:

wang wang

miao miao

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

看 ServiceLoader 類的簽名類的成員變量:

public final class ServiceLoader<S>
    implements Iterable<S>
{

    private static final String PREFIX = "META-INF/services/";

    // 代表被加載的類或者接口
    private final Class<S> service;

    // 用于定位,加載和實(shí)例化 providers 的類加載器
    private final ClassLoader loader;

    // 創(chuàng)建 ServiceLoader 時(shí)采用的訪問控制上下文
    private final AccessControlContext acc;

    // 緩存 providers,按實(shí)例化的順序排列
    private LinkedHashMap<String,S> providers = new LinkedHashMap<>();

    // 懶查找迭代器
    private LazyIterator lookupIterator;
	······
}

參考具體源碼,梳理了一下,實(shí)現(xiàn)的流程如下:

  1. 應(yīng)用程序調(diào)用 ServiceLoader.load 方法,ServiceLoader.load方法內(nèi)先創(chuàng)建一個(gè)新的 ServiceLoader,并實(shí)例化該類中的成員變量,包括:
    1. loader(ClassLoader 類型,類加載器)
    2. acc(AccessControlContext 類型,訪問控制器)
    3. providers(LinkedHashMap 類型,用于緩存加載成功的類)
    4. lookupIterator(實(shí)現(xiàn)迭代器功能)
  1. 應(yīng)用程序通過迭代器接口獲取對(duì)象實(shí)例
    1. ServiceLoader 先判斷成員變量 providers 對(duì)象中(LinkedHashMap 類型)是否有緩存實(shí)例對(duì)象,如果有緩存,直接返回。
    2. 如果沒有緩存,執(zhí)行類的裝載:
      1. 讀取 META-INF/services/ 下的配置文件,獲得所有能被實(shí)例化的類的名稱
      2. 通過反射方法 Class.forName() 加載類對(duì)象,并用 instance() 方法將類實(shí)例化
      3. 把實(shí)例化的類緩存到 providers 對(duì)象中(LinkedHashMap 類型)
      4. 然后返回實(shí)例對(duì)象

SPI 的應(yīng)用場(chǎng)景

概括地說,適用于:調(diào)用者根據(jù)實(shí)際使用需要,啟用、擴(kuò)展、或者替換框架的實(shí)現(xiàn)策略。

比如常見的例子:

  1. 數(shù)據(jù)庫驅(qū)動(dòng)加載接口實(shí)現(xiàn)類的加載
  2. JDBC 加載不同類型數(shù)據(jù)庫的驅(qū)動(dòng)
  3. 日志門面接口實(shí)現(xiàn)類加載
  4. SLF4J 加載不同提供商的日志實(shí)現(xiàn)類

Spring

Spring 中大量使用了 SPI,比如:對(duì) servlet3.0 規(guī)范對(duì) ServletContainerInitializer 的實(shí)現(xiàn)、自動(dòng)類型轉(zhuǎn)換 Type Conversion SPI(Converter SPI、Formatter SPI)等

Dubbo

Dubbo 中也大量使用 SPI的方式實(shí)現(xiàn)框架的擴(kuò)展,不過它對(duì) java 提供的原生 SPI 做了封裝,允許用戶擴(kuò)展實(shí)現(xiàn) Filter 接口。文章來源地址http://www.zghlxwxcb.cn/news/detail-658915.html

到了這里,關(guān)于什么是 SPI,和API有什么區(qū)別?的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 編程開發(fā)8大語言詳解,為什么Java是我最推薦的?

    編程開發(fā)8大語言詳解,為什么Java是我最推薦的?

    很多沒有接觸過編程語言的同學(xué),都會(huì)覺得編程開發(fā)特別高端和神奇,擔(dān)心理解不了更擔(dān)心學(xué)不會(huì)。 當(dāng)然,也有人會(huì)認(rèn)為,你既然是做編程的,那么你應(yīng)該什么都會(huì),什么軟件的開發(fā)都能完成,這是平哥經(jīng)常聽到的兩種聲音。 在此,平哥需要給大家科普一下, 編程確實(shí)改變

    2024年02月05日
    瀏覽(18)
  • Java開發(fā)手冊(cè)之單元測(cè)試,軟件測(cè)試端簡(jiǎn)單易用的SPI框架

    Java開發(fā)手冊(cè)之單元測(cè)試,軟件測(cè)試端簡(jiǎn)單易用的SPI框架

    【推薦】編寫單元測(cè)試代碼遵守 BCDE 原則,以保證被測(cè)試模塊的交付質(zhì)量。 B:Border,邊界值測(cè)試,包括循環(huán)邊界、特殊取值、特殊時(shí)間點(diǎn)、數(shù)據(jù)順序等。 C:Correct,正確的輸入,并得到預(yù)期的結(jié)果。 D:Design,與設(shè)計(jì)文檔相結(jié)合,來編寫單元測(cè)試。 E:Error,強(qiáng)制錯(cuò)誤信息輸

    2024年04月25日
    瀏覽(40)
  • Java和Java大數(shù)據(jù)有什么區(qū)別?

    Java和Java大數(shù)據(jù)有什么區(qū)別?

    分別提起Java或者大數(shù)據(jù),很多人對(duì)此都一目了然,但對(duì)于Java大數(shù)據(jù)這樣一個(gè)新鮮名詞,多少有些疑惑。那Java和Java大數(shù)據(jù)學(xué)習(xí)的內(nèi)容是一樣的嗎?兩者有什么區(qū)別呢?今天就從Java和Java大數(shù)據(jù)的以下方面談?wù)剝烧叩膮^(qū)別。 1.Java和大數(shù)據(jù)的關(guān)系 Java是計(jì)算機(jī)的一門編程語言;可

    2024年02月05日
    瀏覽(20)
  • Java語言開發(fā)在線小說推薦網(wǎng) 小說推薦系統(tǒng) 基于用戶、物品的協(xié)同過濾推薦算法 SSM(Spring+SpringMVC+Mybatis)開發(fā)框架 大數(shù)據(jù)、人工智能、機(jī)器學(xué)習(xí)開發(fā)

    Java語言開發(fā)在線小說推薦網(wǎng) 小說推薦系統(tǒng) 基于用戶、物品的協(xié)同過濾推薦算法 SSM(Spring+SpringMVC+Mybatis)開發(fā)框架 大數(shù)據(jù)、人工智能、機(jī)器學(xué)習(xí)開發(fā)

    1、開發(fā)工具和使用技術(shù) MyEclipse10/Eclipse/IDEA,jdk1.8,mysql5.5/mysql8,navicat數(shù)據(jù)庫管理工具,tomcat,SSM(spring+springmvc+mybatis)開發(fā)框架,jsp頁面,javascript腳本,jquery腳本,bootstrap前端框架(用戶端),layui前端框架(管理員端),layer彈窗組件等。 2、實(shí)現(xiàn)功能 前臺(tái)用戶包含:注

    2023年04月26日
    瀏覽(99)
  • 【Java基礎(chǔ)】走進(jìn)Java:JDK和JRE分別是什么?它們有什么區(qū)別?

    ??Java是一門非常流行的編程語言,被廣泛應(yīng)用于各個(gè)領(lǐng)域的軟件開發(fā)。在Java開發(fā)中,JRE和JDK是兩個(gè)重要的概念,它們有著不同的作用和功能。本篇技術(shù)博客將會(huì)介紹JRE和JDK的概念、組成部分、安裝和配置、以及它們之間的區(qū)別和聯(lián)系。希望對(duì)Java開發(fā)者們有所幫助。 ??

    2023年04月14日
    瀏覽(29)
  • 什么是JPA(Java Persistence API)?

    JPA(Java Persistence API)是一種Java EE規(guī)范,用于簡(jiǎn)化對(duì)象-關(guān)系映射(ORM)的開發(fā)。它提供了一組API和標(biāo)準(zhǔn),用于管理Java對(duì)象與關(guān)系數(shù)據(jù)庫之間的映射,使得開發(fā)人員可以以面向?qū)ο蟮姆绞絹碓L問和持久化數(shù)據(jù)。 JPA的主要特點(diǎn)和優(yōu)勢(shì)包括: 1. 對(duì)象-關(guān)系映射:JPA通過注解或XML配

    2024年02月15日
    瀏覽(12)
  • 【六袆 - Go】 Go vs Java;Java語言對(duì)比Go語言的區(qū)別

    Golang VS Java 下面是Java和Go語言在運(yùn)行環(huán)境方面的對(duì)比矩陣: Java Go 運(yùn)行環(huán)境 Java虛擬機(jī)(JVM) Go運(yùn)行時(shí)(Go Runtime) 編譯方式 源代碼編譯為字節(jié)碼 源代碼直接編譯為機(jī)器碼 內(nèi)存管理 自動(dòng)垃圾回收 自動(dòng)垃圾回收 并發(fā)模型 多線程 Goroutine和通道 類型系統(tǒng) 靜態(tài)類型 靜態(tài)類型 語言

    2024年01月19日
    瀏覽(25)
  • 【JAVA】Iterator 和 ListIterator 有什么區(qū)別?

    【JAVA】Iterator 和 ListIterator 有什么區(qū)別?

    ?? 個(gè)人博客: 個(gè)人主頁 ?? 個(gè)人專欄: ? ?? JAVA? ? ??? 功不唐捐,玉汝于成 目錄 在Java中,遍歷集合是日常編程中常見的任務(wù),而 Iterator 和 ListIterator 作為遍歷集合的兩個(gè)主要接口,提供了不同的功能和靈活性。通過深入了解它們之間的差異,我們能夠更好地選擇適合

    2024年02月02日
    瀏覽(13)
  • 【JAVA】concurrentHashMap和HashTable有什么區(qū)別

    【JAVA】concurrentHashMap和HashTable有什么區(qū)別

    ?? 個(gè)人博客: 個(gè)人主頁 ?? 個(gè)人專欄: JAVA ???? 功不唐捐,玉汝于成 目錄 前言 正文 同步性質(zhì): 性能: 允許空鍵值(Allow Nulls): 迭代器(Iterator): 繼承關(guān)系: 結(jié)語 ?我的其他博客 在Java的集合框架中, ConcurrentHashMap 和 HashTable 都提供了線程安全的哈希表實(shí)現(xiàn),用

    2024年01月16日
    瀏覽(25)
  • Java 成員變量與局部變量有什么區(qū)別?

    Java 成員變量與局部變量有什么區(qū)別?

    節(jié)選自JavaGuide(Github 標(biāo)星 134k star!「Java學(xué)習(xí) + 面試指南」一份涵蓋大部分 Java 程序員所需要掌握的核心知識(shí)) 語法形式 :從語法形式上看,成員變量是屬于類的,而局部變量是在代碼塊或方法中定義的變量或是方法的參數(shù);成員變量可以被 public , private , static 等修飾符所修

    2024年02月05日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包