dubbo SPI 机制 和 JDK SPI
Java SPI
ServerLoad.load 加载接口的实现类,只需要把实现类的全限定名配置到META-INF/services/文件夹下,然后要一个文件,文件名为接口名,内容就是实现类的全限定名

dubbo SPI
dubbo 也用了spi思想,不过没有用jdk的spi机制,是自己实现的一套spi机制。
Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
这行代码就是dubbo里大量使用的,就是对很多组件,都是保留一个接口和多个实现,然后在系统运行的时候动态根据配置去找到对应的实现类。如果你没配置,那就走默认的实现。
@SPI("dubbo")
public interface Protocol {
int getDefaultPort();
@Adaptive
<T> Exporter<T> export(Invoker<T> invoker) throws RpcException;
@Adaptive
<T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
void destroy();
default List<ProtocolServer> getServers() {
return Collections.emptyList();
}
}
在dubbo自己的jar里,在/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol文件中:
filter=org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper
listener=org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper
mock=org.apache.dubbo.rpc.support.MockProtocol
dubbo=org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol
injvm=org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol
http=org.apache.dubbo.rpc.protocol.http.HttpProtocol
rmi=org.apache.dubbo.rpc.protocol.rmi.RmiProtocol
hessian=org.apache.dubbo.rpc.protocol.hessian.HessianProtocol
org.apache.dubbo.rpc.protocol.webservice.WebServiceProtocol
thrift=org.apache.dubbo.rpc.protocol.thrift.ThriftProtocol
native-thrift=org.apache.dubbo.rpc.protocol.nativethrift.ThriftProtocol
memcached=org.apache.dubbo.rpc.protocol.memcached.MemcachedProtocol
redis=org.apache.dubbo.rpc.protocol.redis.RedisProtocol
rest=org.apache.dubbo.rpc.protocol.rest.RestProtocol
xmlrpc=org.apache.dubbo.xml.rpc.protocol.xmlrpc.XmlRpcProtocol
grpc=org.apache.dubbo.rpc.protocol.grpc.GrpcProtocol
registry=org.apache.dubbo.registry.integration.RegistryProtocol
service-discovery-registry=org.apache.dubbo.registry.client.ServiceDiscoveryRegistryProtocol
qos=org.apache.dubbo.qos.protocol.QosProtocolWrapper
@SPI("dubbo"),这个注解就是用来确定具体加载哪个实现类,通过dubbo作为key可以找到默认的实现就是
dubbo=org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol
@Adaptive这个注解修饰在方法上,该接口会生成一个代理类 Protocol$Adaptive ,核心代码如下:
@Adaptive
<T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
方法中实现:
Protocol extension =(Protocol)ExtensionLoader
.getExtensionLoader(Protocol.class)
.getExtension(extName);
return extension.refer(arg0, arg1);
ExtensionLoader 会根据@SPI("dubbo")找到org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol来调用方法。

浙公网安备 33010602011771号