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

JDK與Dubbo中的SPI詳細介紹

 更新時間:2022年09月02日 10:58:25   作者:悠然予夏  
這篇文章主要介紹了JDK中的SPI與Dubbo中的SPI,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

1、SPI簡介

SPI 全稱為 (Service Provider Interface) ,是JDK內置的一種服務提供發(fā)現機制。 目前有不少框架用它來做服務的擴展發(fā)現,簡單來說,它就是一種動態(tài)替換發(fā)現的機制。使用SPI機制的優(yōu)勢是實現解耦,使得第三方服務模塊的裝配控制邏輯與調用者的業(yè)務代碼分離。

2、JDK中的SPI

Java中如果想要使用SPI功能,先提供標準服務接口,然后再提供相關接口實現和調用者。這樣就可以通過SPI機制中約定好的信息進行查詢相應的接口實現。

SPI遵循如下約定:

  • 當服務提供者提供了接口的一種具體實現后,在META-INF/services目錄下創(chuàng)建一個以“接口全限定名”為命名的文件,內容為實現類的全限定名;
  • 接口實現類所在的jar包放在主程序的classpath中;
  • 主程序通過java.util.ServiceLoader動態(tài)裝載實現模塊,它通過掃描META-INF/services目錄下的配置文件找到實現類的全限定名,把類加載到JVM;
  • SPI的實現類必須攜帶一個無參構造方法;

入門案例

模塊結構如下

(1)api模塊

此模塊創(chuàng)建了一個接口,供后續(xù)模塊使用

package com.lagou.service;
public interface HelloService {
    String sayHello();
}

(2)impl模塊

此模塊中提供了api模塊接口的實現類,并且在resource目錄下,創(chuàng)建了配置文件。

實現類

package com.lagou.service.impl;
import com.lagou.service.HelloService;
public class HumanHelloService implements HelloService {
    @Override
    public String sayHello() {
        return "hello world";
    }
}

配置文件(名稱為接口全限定名, 內容為接口實現類全限定類名)

com.lagou.service.impl.HumanHelloService

(3)main模塊

提供了測試jdk-spi的的類

package com.lagou.test;
import com.lagou.service.HelloService;
import java.util.ServiceLoader;
public class JavaSpiMain {
    public static void main(String[] args) {
        final ServiceLoader<HelloService> helloServices = ServiceLoader.load(HelloService.class);
        for (HelloService helloService : helloServices) {
            System.out.println(helloServices.getClass().getName() + ";" + helloService.sayHello());
        }
    }
}

3、Dubbo中的SPI

dubbo中大量的使用了SPI來作為擴展點,通過實現同一接口的前提下,可以進行定制自己的實現類。比如比較常見的協議,負載均衡,都可以通過SPI的方式進行定制化,自己擴展。Dubbo中已經存在的所有已經實現好的擴展點。

下圖中則是Dubbo中默認提供的負載均衡策略。

4、Dubbo中擴展點使用方式

我們使用三個項目來演示Dubbo中擴展點的使用方式,一個主項目main,一個服務接口項目api,一個服務實現項目impl。

(1)api模塊

往pom.xml中導入dubbo依賴

       <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.7.5</version>
        </dependency>

創(chuàng)建接口,并在接口上添加上@SPI注解

package com.lagou.service;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.Adaptive;
import org.apache.dubbo.common.extension.SPI;
@SPI
public interface HelloService {
    String sayHello();
}

(2)impl模塊

導入 api項目 的依賴

建立實現類

package com.lagou.service;
public class HumanHelloService implements HelloService{
    @Override
    public String sayHello() {
        return "hello 你好";
    }
}

SPI進行聲明操作,在resources 目錄下創(chuàng)建目錄META-INF/dubbo 目錄,在目錄下創(chuàng)建名稱為接口的全限定類名的文件,文件內部配置實現類名稱和對應的全限定名:

human=com.lagou.service.HumanHelloService

(3)main模塊

導入坐標、接口項目和實現類項目

創(chuàng)建DubboSpiMain

和原先調用的方式不太相同, dubbo 有對其進行自我重新實現 需要借助ExtensionLoader,創(chuàng)建新的運行項目。這里demo中的示例和java中的功能相同,查詢出所有的已知實現,并且調用

package com.lagou;
import com.lagou.service.HelloService;
import org.apache.dubbo.common.extension.ExtensionLoader;
import java.util.Set;
public class DubboSpiMain {
    public static void main(String[] args) {
        // 獲取擴展加載器
        ExtensionLoader<HelloService> extensionLoader = ExtensionLoader.getExtensionLoader(HelloService.class);
        // 遍歷所有支持的擴展點   META-INF.dubbo
        Set<String> extensions = extensionLoader.getSupportedExtensions();
        for (String extension : extensions) {
            String result = extensionLoader.getExtension(extension).sayHello();
            System.out.println(result);
        }
    }
}

(4)dubbo自己做SPI的目的

1. JDK 標準的 SPI 會一次性實例化擴展點所有實現,如果有擴展實現初始化很耗時,但如果沒用上也加載,會很浪費資源

2. 如果有擴展點加載失敗,則所有擴展點無法使用

3. 提供了對擴展點包裝的功能(Adaptive),并且還支持通過set的方式對其他的擴展點進行注入

5、DubboSPI中的Adaptive功能

Dubbo中的Adaptive功能,主要解決的問題是如何動態(tài)的選擇具體的擴展點。通過getAdaptiveExtension 統一對指定接口對應的所有擴展點進行封裝,通過URL的方式對擴展點來進行動態(tài)選擇。 (dubbo中所有的注冊信息都是通過URL的形式進行處理的。)這里同樣采用相同的方式進行實現。

(1)創(chuàng)建接口

api中的HelloService 擴展如下方法, 與原先類似,在sayHello中增加Adaptive 注解,并且在參數中提供URL參數.注意這里的URL參數的類為org.apache.dubbo.common.URL,其中@SP可以指定一個字符串參數,用于指明該SPI的默認實現。

package com.lagou.service;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.Adaptive;
import org.apache.dubbo.common.extension.SPI;
@SPI("human") // 這個human對應配置文件中的human
public interface HelloService {
    String sayHello();
    @Adaptive
    String sayHello(URL url);
}

(2)創(chuàng)建實現類

與上面Service實現類代碼相似,只需增加URL形參即可

package com.lagou.service;
import org.apache.dubbo.common.URL;
public class HumanHelloService implements HelloService{
    @Override
    public String sayHello() {
        return "hello 你好";
    }
    @Override
    public String sayHello(URL url) {
        return "hello url";
    }
}

(3)編寫DubboAdaptiveMain

最后在獲取的時候方式有所改變,需要傳入URL參數,并且在參數中指定具體的實現類參數

package com.lagou;
import com.lagou.service.HelloService;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
public class DubboAdaptiveMain {
    public static void main(String[] args) {
        URL url = URL.valueOf("test://localhost?hello.service=human");
        HelloService adaptiveExtension = ExtensionLoader.getExtensionLoader(HelloService.class).getAdaptiveExtension();
        String hello = adaptiveExtension.sayHello(url);
        System.out.println(hello);
    }
}

注意:

  • 因為在這里只是臨時測試,所以為了保證URL規(guī)范,前面的信息均為測試值即可,關鍵的點在于hello.service 參數,這個參數的值指定的就是具體的實現方式。關于為什么叫hello.service 是因為這個接口的名稱,其中后面的大寫部分被dubbo自動轉碼為. 分割。
  • 通過getAdaptiveExtension 來提供一個統一的類來對所有的擴展點提供支持(底層對所有的擴展點進行封裝)。
  • 調用時通過參數中增加URL 對象來實現動態(tài)的擴展點使用。
  • 如果URL沒有提供該參數,則該方法會使用默認在SPI 注解中聲明的實現。

到此這篇關于JDK與Dubbo中的SPI詳細介紹的文章就介紹到這了,更多相關JDK與Dubbo的SPI內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 解決maven父子工程install的時候排除某些子模塊,讓子模塊不install問題

    解決maven父子工程install的時候排除某些子模塊,讓子模塊不install問題

    在Maven父子工程中,如果希望某個子模塊不被安裝到本地倉庫,可以在該子模塊的`pom.xml`文件中添加以下配置: ```xml ... org.apache.maven.plugins maven-install-plugin 2.5.2 true
    2024-12-12
  • 新版idea工具欄菜單展開與合并顯示方式

    新版idea工具欄菜單展開與合并顯示方式

    文章介紹了如何在新版IDEA中調整工具欄菜單的顯示方式,通過取消勾選設置中的某個選項,可以使菜單展開更加方便
    2025-01-01
  • Spring與Struts整合之讓Spring管理控制器操作示例

    Spring與Struts整合之讓Spring管理控制器操作示例

    這篇文章主要介紹了Spring與Struts整合之讓Spring管理控制器操作,結合實例形式詳細分析了Spring管理控制器相關配置、接口實現與使用技巧,需要的朋友可以參考下
    2020-01-01
  • nacos配置實例權重不生效問題

    nacos配置實例權重不生效問題

    這篇文章主要介紹了nacos配置實例權重不生效問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • SpringBoot接口或方法進行失敗重試的實現方式

    SpringBoot接口或方法進行失敗重試的實現方式

    為了防止網絡抖動,影響我們核心接口或方法的成功率,通常我們會對核心方法進行失敗重試,如果我們自己通過for循環(huán)實現,會使代碼顯得比較臃腫,所以本文給大家介紹了SpringBoot接口或方法進行失敗重試的實現方式,需要的朋友可以參考下
    2024-07-07
  • 基于Java實現連連看游戲的示例代碼

    基于Java實現連連看游戲的示例代碼

    連連看游戲顧名思義就是找出具有關聯關系的事物并進行相應處理。本文將用java語言實現這一經典游戲,采用了swing技術進行了界面化處理,感興趣的可以了解一下
    2022-09-09
  • SpringBoot和前端Vue的跨域問題及解決方案

    SpringBoot和前端Vue的跨域問題及解決方案

    所謂跨域就是從 A 向 B 發(fā)請求,如若他們的地址協議、域名、端口都不相同,直接訪問就會造成跨域問題,跨域是非常常見的現象,這篇文章主要介紹了解決SpringBoot和前端Vue的跨域問題,需要的朋友可以參考下
    2023-11-11
  • Java中的ReentrantLock原理解析

    Java中的ReentrantLock原理解析

    這篇文章主要介紹了Java中的ReentrantLock原理解析,ReentrantLock是Java中的一個線程同步工具,它提供了比synchronized更靈活和強大的功能。它是一個可重入的互斥鎖,意味著同一個線程可以多次獲取該鎖,而不會發(fā)生死鎖,需要的朋友可以參考下
    2023-11-11
  • Java有哪些操作字符串的類?區(qū)別在哪?

    Java有哪些操作字符串的類?區(qū)別在哪?

    今天給大家愛帶來的是關于Java的相關知識,文章圍繞著Java操作字符串的類展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • 深入了解Java File分隔符和Path分隔符的使用

    深入了解Java File分隔符和Path分隔符的使用

    不同的操作系統使用不同的字符作為文件和路徑分隔符。當我們的應用程序需要在多個平臺上運行時,我們需要正確處理這些問題。Java幫助我們選擇一個合適的分隔符,本文就來聊聊Java中File分隔符和 Path分隔符的使用
    2022-07-07

最新評論