Dubbo內核實現之SPI簡單介紹

Dubbo採用微內核+插件體系,使得設計優雅,擴展性強。那所謂的微內核+插件體系是如何實現的呢!即咱們定義了服務接口標準,讓廠商去實現(若是不瞭解spi的請谷歌百度下), jdk經過ServiceLoader類實現spi機制的服務查找功能。插件

JDK實現spi服務查找: ServiceLoader設計

首先定義下示例接口code

package com.example;

public interface Spi {

booleanisSupport(String name);

String sayHello();

}

ServiceLoader會遍歷全部jar查找META-INF/services/com.example.Spi文件blog

package com.a.example;

public class SpiAImpl implements Spi {

publicboolean isSupport(String name) {
return"SPIA".equalsIgnoreCase(name.trim());
}


public String syaHello() {
return 「hello 我是廠商A」;
}

}

在A廠商提供的jar包中的META-INF/services/com.example.Spi文件內容爲:接口

com.a.example.SpiAImpl #廠商A的spi實現全路徑類名get

B廠商提供實現for循環

package com.b.example;

public class SpiBImpl implements Spi {

publicboolean isSupport(String name) {
return"SPIB".equalsIgnoreCase(name.trim());
}

public String syaHello() {
return 「hello 我是廠商B」;
}

}

在B廠商提供的jar包中的META-INF/services/com.example.Spi文件內容爲:class

com.b.example.SpiBImpl #廠商B的spi實現全路徑類名test

ServiceLoader.load(Spi.class)讀取廠商A、B提供jar包中的文件,ServiceLoader實現了Iterable接口可經過while for循環語句遍歷出全部實現。百度

一個接口多種實現,就如策略模式同樣提供了策略的實現,可是沒有提供策略的選擇, 使用方能夠根據isSupport方法根據業務傳入廠商名來選擇具體的廠商。

public class SpiFactory {

//讀取配置獲取全部實現
privatestatic ServiceLoader spiLoader = ServiceLoader.load(Spi.class);

//根據名字選取對應實現
publicstatic Spi getSpi(String name) {
for(Spi spi : spiLoader) {
if(spi.isSupport(name) ) {
returnspi;
}
}
returnnull;
}
}

SPI接口定義

定義了@SPI註解

  1. public @interface SPI {
    Stringvalue() default ""; //指定默認的擴展點
    }

     

只有在接口打了@SPI註解的接口類纔會去查找擴展點實現,會依次從這幾個文件中讀取擴展點

  1. META-INF/dubbo/internal/ //dubbo內部實現的各類擴展都放在了這個目錄了
    
    META-INF/dubbo/
    
    META-INF/services/

     

咱們以Protocol接口爲例, 接口上打上SPI註解,默認擴展點名字爲dubbo

  1. @SPI("dubbo")
    public interface Protocol{
    
    }

     

具體實現的類有:

因此說:Remoting實現是Dubbo協議的實現。

相關文章
相關標籤/搜索