dubbo源码笔记-基于 dubbo-2.6.4
1.源码码的下载与更新
dubbo官网:http://dubbo.apache.org/zh-cn/docs/source_code_guide/refer-service.html
需要更新源代码到官网建议版本,源码相同,看起来会顺畅很多
dubbo-2.6.4 是确实存在并且可以更新的,参考以下命令
git git --set-upstream-to=refs/tags/dubbo-2.6.4
git fetch --tags
git pull origin dubbo-2.6.4 dubbo-2.6.4
1.解析自定义bean
1、扩展spring标签
spring.handlers和spring.schemas文件定义好了之后,接下来就是定义自己的NamespaceHandler处理类
dubbo的处理类是 DubboNamespaceHandler,spring将上下文传给DubboNamespaceHandler,解析出来的bean就可以放入spring容器中,交给spring管理
2、解析自定义bean
解析出来的bean包含 service-用于服务导出 ,reference-用于服务引用
2.dubbospi
3.自适应拓展机制
4.服务导出
1、初始化
1.1 ServiceBean 是进行服务导出的入口,起实现了InitializingBean 和 ApplicationListener
1.2 Dubbo 支持两种服务导出方式,分别延迟导出和立即导出。延迟导出的入口是 ServiceBean
的 afterPropertiesSet
方法,立即导出的入口是 ServiceBean
的onApplicationEvent
方法
1.3 onApplicationEvent在spring容器初始化后自动执行,方法中会判断是否延迟,需要注意下isDelay()方法的含义与字面意思相反
1.4 export() 实现服务导出
1.5 afterPropertiesSet 延迟导出
1.6 配置检查 checkApplication(); checkRegistry(); checkProtocol();
1.7 doExportUrls(); 正式导出
1.8 加载注册中心链接 loadRegistries
1.9 遍历协议,每个协议都在所有的注册中心上面进行注册
// 遍历 protocols,并在每个协议下导出服务
for (ProtocolConfig protocolConfig : protocols) { doExportUrlsFor1Protocol(protocolConfig, registryURLs); }
2.0 组装dubbo.URL
2.1:为服务生成代理类
public void setPropertyValue(Object o, String n, Object v){ com.alibaba.dubbo.demo.DemoService w; try{ w = ((com.alibaba.dubbo.demo.DemoService)$1); }catch(Throwable e){ throw new IllegalArgumentException(e); } throw new com.alibaba.dubbo.common.bytecode.NoSuchPropertyException("Not found property \""+$2+"\" filed or setter method in class com.alibaba.dubbo.demo.DemoService."); }
public Object getPropertyValue(Object o, String n){ com.alibaba.dubbo.demo.DemoService w; try{ w = ((com.alibaba.dubbo.demo.DemoService)$1); }catch(Throwable e){ throw new IllegalArgumentException(e); } throw new com.alibaba.dubbo.common.bytecode.NoSuchPropertyException("Not found property \""+$2+"\" filed or setter method in class com.alibaba.dubbo.demo.DemoService."); }
public Object invokeMethod(Object o, String n, Class[] p, Object[] v) throws java.lang.reflect.InvocationTargetException{ com.alibaba.dubbo.demo.DemoService w; try{ w = ((com.alibaba.dubbo.demo.DemoService)$1); }catch(Throwable e){ throw new IllegalArgumentException(e); } try{ if( "sayHello".equals( $2 ) && $3.length == 1 ) { return ($w)w.sayHello((java.lang.String)$4[0]); } } catch(Throwable e) { throw new java.lang.reflect.InvocationTargetException(e); } throw new com.alibaba.dubbo.common.bytecode.NoSuchMethodException("Not found method \""+$2+"\" in class com.alibaba.dubbo.demo.DemoService."); }
dubbo://202.106.199.34:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&bind.ip=202.106.199.34&bind.port=20880&dubbo=2.0.2&generic=false&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=58355&qos.port=22222&side=provider×tamp=1574121613254
2.2 dubbo协议则打开netty服务端
2.3:zk注册中心则通过zk客户端向注册中心注册服务url
5.服务引入
1:服务引用的入口方法为 ReferenceBean 的 getObject 方法,该方法定义在 Spring 的 FactoryBean 接口中,ReferenceBean 实现了这个方法
2:检查与加载配置 application,interface
3:创建代理 ref = createProxy(map)
4:加载注册中心 url List<URL> us = loadRegistries(false);
5:注册服务消费者,在 consumers 目录下新节点
6:订阅 providers、configurators、routers 等节点数据
7:从注册中心获取服务端信息后,通过dubbo协议创建netty链接
8:创建代理对象,内部调用invoke ,通过netty进行通信
参考资料
整体参考
https://www.jianshu.com/nb/34090253 很多内容 - 写的很好