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註解
public @interface SPI { Stringvalue() default ""; //指定默認的擴展點 }
只有在接口打了@SPI註解的接口類纔會去查找擴展點實現,會依次從這幾個文件中讀取擴展點
META-INF/dubbo/internal/ //dubbo內部實現的各類擴展都放在了這個目錄了 META-INF/dubbo/ META-INF/services/
咱們以Protocol接口爲例, 接口上打上SPI註解,默認擴展點名字爲dubbo
@SPI("dubbo") public interface Protocol{ }
具體實現的類有:
因此說:Remoting實現是Dubbo協議的實現。