dubbo SPI功能解析(一)

SPI配置說明

若是須要擴展Dubbo Protocol接口實現,須要在本身的擴展jar中新增文本文件 META-INF/dubbo/com.alibaba.dubbo.rpc.Protocol ,文件內容爲java

xxx=com.alibaba.xxx.XxxProtocol
複製代碼

實現類爲bash

package com.alibaba.xxx;
 
import com.alibaba.dubbo.rpc.Protocol;
 
public class XxxProtocol implements Protocol { 
    // ...
}
複製代碼

SPI的擴展配置都是經過配置標籤屬性來實現的app

<dubbo:protocol name="xxx" />
複製代碼

SPI特性

SPI自動包裝SPI Auto Wrapthis

package com.alibaba.xxx;
 
import com.alibaba.dubbo.rpc.Protocol;
 
public class XxxProtocolWrapper implements Protocol {
    Protocol impl;
 
    public XxxProtocolWrapper(Protocol protocol) { impl = protocol; }
 
    //after interface method is executed,the method in extension will be executed
    public void refer() {
        //... some operation
        impl.refer();
        // ... some operation
    }
 
    // ...
}
複製代碼

SPI包裝器實現類也實現了SPI接口,包裝器類名必須以Wrapper結尾,構造器方法須要傳入真正的SPI實現類,當經過ExtensionLoader SPI實現類加載器加載SPI實現類時,會自動返回具體實現類的包裝實現,經過這種方式類型了相似Spring AOP的功能。包裝器實現類能夠有多個,這樣能夠實現鏈式結構。url

最典型的實現見ProtocolFilterWrapper將Protocol協議生成的Invoker實現包裝了一層Filter過濾器鏈spa

SPI依賴注入(自動加載)

public interface CarMaker {
    Car makeCar();
}
 
public interface WheelMaker {
    Wheel makeWheel();
}
複製代碼

假設有兩個SPI接口CarMaker,WheelMaker如上 CarMaker implementation:代理

public class RaceCarMaker implements CarMaker {
    WheelMaker wheelMaker;
 
    public setWheelMaker(WheelMaker wheelMaker) {
        this.wheelMaker = wheelMaker;
    }
 
    public Car makeCar() {
        // ...
        Wheel wheel = wheelMaker.makeWheel();
        // ...
        return new RaceCar(wheel, ...);
    }
}
複製代碼

當經過ExtensionLoader來加載CarMaker實現時,會自動加載WheelMaker的實現類設置到wheelMaker的屬性中實現依賴注入的功能,若是WheelMaker有多個實現類,會建立WheelMaker自適應實現做爲實現類。若是隻有一個實現類既爲該實現類。code

SPI自適應實現

public interface CarMaker {
    Car makeCar(URL url);
}
 
public interface WheelMaker {
    Wheel makeWheel(URL url);
}

public class RaceCarMaker implements CarMaker {
    WheelMaker wheelMaker;
 
    public setWheelMaker(WheelMaker wheelMaker) {
        this.wheelMaker = wheelMaker;
    }
 
    public Car makeCar(URL url) {
        // ...
        Wheel wheel = wheelMaker.makeWheel(url);
        // ...
        return new RaceCar(wheel, ...);
    }
}
複製代碼

能夠看到SPI接口實現類方法都增長了URL參數,最關鍵的Wheel wheel = wheelMaker.makeWheel(url); wheelMaker自適應類實現了一個薄薄的代理層,會根據Url對象中預約義的key,默認使用SPI的類名簡稱 url.get("wheelMaker")獲取真正的實現名稱,而後經過ExtensionLoader獲取真實實現名對應的實現類。 dubbo將XML配置中全部的信息都封裝在URL中,自適應實現類經過修改XML配置切換具體實現類的。對象

相關文章
相關標籤/搜索