Dubbo源码解读01SPI机制、扩展点及服务发布流程

一.SPI(service provider interface)

JAVA SPI(JDK内置服务发现机制,用于动态扩展)

JDK定义接口规范:com.xxx.xxx.Driver

其他厂商根据结构规范实现实现类:com.mysql.jdbc.Driver(implement Driver)

文件位置:resources/META-INF/services/com.xxx.xxx.Driver(接口全路径)

文件内容:com.mysql.jdbc.Driver(实现类路径)

 

缺点:

1.全部加载

2.加载失败会报错

 

DUBBO SPI

1.文件位置:/META-INF/dubbo;/META-INF/dubbo/internal;/META-INF/services

2.文件名:同java spi

3.内容:key=value

 

二.Dubbo SPI实现

@SPI

表示当前接口是一个扩展点,可以自己扩展实现,默认扩展点是DubboProtocol

@Adaptive

定义在类级别表示自适应适配器

定义在方法级别表示需要动态加载生成一个适配器

 

Extension.getExtensionLoader(Protocol.class).getExtension(“dubbo”);

Protocol protocol = Extension.getExtensionLoader(Protocol.class).getAdaptiveExtension();

 

Extension.getExtensionLoader.getAdaptiveExtension

getExtensionLoader(通过一个Class参数去获

得一个ExtensionLoader对象,有点类似一个工厂模式)

getAdaptiveExtension(去获得一个自适应的扩展点)

createAdaptiveExtension

injectExtension(可以实现扩展点的注入)

getAdaptiveExtensionClass

createAdaptiveExtensionClass(动态创建一个扩展点,生成Protocol$Adaptive)

getExtensionClasses(加载所有路径下的扩展点)

loadExtensionClasses(加载dubbo spi路径下的扩展点)

 

三.服务发布流程

记录下整体调用流程,没有太详细的解释,可以自己debug调用下看结果

1.解析spring配置文件

spring支持:/META-INF/spring.handlers定义了xml解析类DubboNamespaceHandler

/META-INF/spring.schemas定义了xsd文件dubbo.xsd

2.DubboNamespaceHandler.init()调用DubboBeanDefinitionParser对spring标签进行解析

new DubboBeanDefinitionParser(ServiceBean.class, true)

3.ServiceBean进行服务发布做了两件事1)通过netty启动了一个服务监听2)通过zookeeper注册了一个协议地址

ServiceBean实现了InitializingBean,初始化时会调用afterPropertiesSet()方法

ServiceBean.afterPropertiesSet()

1.将解析的xml属性set到对应属性里

2.ServiceConfig.export()-->doExport()-->doExportUrls()-->doExportUrlsFor1Protocol()-->protocol.export(invoker)

ServiceConfig.export():判断是否delay来决定是否Thread.sleep(),调用doExport

doExport():做相应检查校验,调用doExportUrls

doExportUrls():加载注册地址,循环调用doExportUrlsFor1Protocol

doExportUrlsFor1Protocol():通过多种方式获得host,将属性put到map中,把map中地址转为URL,调用protocol.export(invoker)进行服务发布

protocol === Protocol$Adaptive

因为是registryURL

protocol.export==Protocol$Adaptive.export==ExtensionLoader.getExtensionLoader.getExtension("")==RegistryProtocol.export

 

invoker = proxyFactory.getInvoker()

proxyFactory = ProxyFactory&Adaptive ==JavassistProxyFactory

JavassistProxyFactory.getInvoker()

Wrapper.getWrapper()

Wrapper.makeWrapper()

invoker = Wrapper.makeWrapper() = JavassistProxyFactory

protocol.export(invoker):将invoker发布出去放到网络层

invoker:

wrapper(JavassistProxyFactory)

proxy(代理,发布接口的实现类)

type(接口,发布的接口地址)

url(registry://开头的url)

4.RegistryProtocol

1)RegistryProtocol.export().doLocalExport(orginInvoker)本地发布,启动服务

1.1)Invoker<?> invokerDelegete = new InvokerDelegete<T>(originInvoker, getProviderUrl(originInvoker));

由于protocol是注入的,所以:

protocol = ProtocolFilterWrapper(ProtocolListenerWrapper(DubboProtocol))

依次调用相应类的export方法

ProtocolFilterWrapper.export

buildInvokerChain:形成filter链

ProtocolListenerWrapper.export

DubboProtocol.export

1.2)exporter = new ExporterChangeableWrapper<T>((Exporter<T>)protocol.export(invokerDelegete), originInvoker);

 

2)registry = getRegistry(originInvoker);

将registryUrl === registry://转换为registryUrl ===zookeeper://

RegistryFactory 是注入的扩展点 --> RegistryFactory$Adaptive --> ZookeeperRegistryFactory

ZookeeperRegistryFactory.getRegistry --> ZookeeperRegistry

 

3)registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener);

订阅监听

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值