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配置切换具体实现类的。