SPI配置說明
如果需要擴充套件Dubbo Protocol介面實現,需要在自己的擴充套件jar中新增文字檔案 META-INF/dubbo/com.alibaba.dubbo.rpc.Protocol ,檔案內容為
xxx=com.alibaba.xxx.XxxProtocol
複製程式碼
實現類為
package com.alibaba.xxx;
import com.alibaba.dubbo.rpc.Protocol;
public class XxxProtocol implements Protocol {
// ...
}
複製程式碼
SPI的擴充套件配置都是通過配置標籤屬性來實現的
<dubbo:protocol name="xxx" />
複製程式碼
SPI特性
SPI自動包裝SPI Auto Wrap
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的功能。包裝器實現類可以有多個,這樣可以實現鏈式結構。
最典型的實現見ProtocolFilterWrapper將Protocol協議生成的Invoker實現包裝了一層Filter過濾器鏈
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自適應實現作為實現類。如果只有一個實現類既為該實現類。
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配置切換具體實現類的。