仿照java的spi,dubbo實現本身的spi

一、平時遇到過的使用java的spi的例子java

    1)mysql的驅動mysql

        

2)spring-webweb

二、spi的設計目標spring

面向對象的設計裏,模塊之間是接口編程,模塊之間不對實現類進行硬編碼,若是實現類寫死在代碼裏,想要換一種實現,就須要修改代碼,爲了避免在代碼裏寫死,就須要一種服務的發現機制,爲某個接口尋找服務實現的機制,有點相似ioc,將裝配的控制權移交到代碼以外sql

三、spi的約定編程

當一個接口有多個實現類的時候,通常在META-INF/services/目錄下,建立接口的同名文件(接口的包名+文件名)緩存

文件的內容就是接口的實現類的名稱(包名+文件名)ide

而當外部程序裝配這個模塊的時候,就能經過該jar包META-INF/services/裏的配置文件找到具體的實現類名,並裝載實例化,完成模塊的注入。 基於這樣一個約定就能很好的找到服務接口的實現類,而不須要再代碼裏制定。jdk提供服務實現查找的一個工具類java.util.ServiceLoader工具

四、查找接口的實現經過ServiceLoader來完成this

Iterator<UserService> services = ServiceLoader.load(UserService.class).iterator();

五、dubbo爲何要實現本身的spi,而不是用jdk的spi

    1)jdk的spi會一次性實例化一個擴展點的全部實現,初始化會很耗時間,而且沒有用到的實現也會加載,浪費資源

    2)增長了對擴展點ioc和aop的支持,一個擴展點能夠直接setter注入其餘擴展點

六、dubbo的spi的約定

dubbo spi 在JAVA自帶的SPI基礎上加入了擴展點的功能,即每一個實現類都會對應至一個擴展點名稱,其目的是 應用可基於此名稱進行相應的裝配。這樣就解決了jdk加載所有的實現類的缺點了。

dubbo spi 目錄文件

dubbo spi  文件內容:

wanglu=wanglu.dubbo.server.WlFilter

裝配自定義Filter

<dubbo:provider filter="wanglu" timeout="2000" retries="2" id="abc"></dubbo:provider>

 

七、dubbo的spi的源碼解析

        1)dubbo spi的目的:dubbo獲取一個實現類的對象

        2)經過ExtensionLoader實現spi擴展點的加載

        途徑:public T getExtension(String name)

        實現途徑:

         getExtensionLoader(Class<T> type),做用就是爲該Class<T>接口new一個ExtensionLoader,而後緩存起來。

         getAdaptiveExtension()  獲取一個擴展裝飾類的對象,這個類有一個規則,若是他沒有@Adaptive註解,就動態建立一個裝飾類,例如:       Protocol$Adaptive對象

       getExtension(String name)獲取一個對象

    3)源碼

---------------------------------------------------ExtensionLoader.getExtensionLoader(Class<T> type)
ExtensionLoader.getExtensionLoader(Container.class)
-->this.type = type;
-->objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
   -->ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
      -->this.type = type;
      -->objectFactory = null;

執行以上的代碼,完成了兩個屬性的初始化 一、每一個ExtensionLoader都包含兩個值type和objectFactory     <T> type  //構造器初始化要獲得的接口名     ExtensionFactory objectFactory 構造器,初始化時AdaptiveExtensionFactory【SpiExtensionFactory】 二、new 一個ExtensionLoader都存儲在ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS 三、關於objectFactory的一些細節     objectFactory 就是ExtensionFactory 經過ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension()來實現的,可是objectFactory 爲空     objectFactory就是dubbo的IOC提供全部對象的

相關文章
相關標籤/搜索