4.消费者是如何调用的
我们先看下消费者的配置
然后我们回到最开始xml解析的过程
看到消费者的reference标签对应的是ReferenceBean,我们打开ReferenceBean
ReferenceBean跟serviceBean是差不多的,只不过只实现了ApplicationContextAware,InitializingBean两个接口,setApplicationContext方法很简单,所以我们直接看afterPropertiesSet方法就行。
这个方法比较简单,跟serviceBean的差不多,主要就是一些变量数据的初始化。然后这里不像serviceBean一样需要打开netty服务,变量初始化就好了,我主要关注referenceBean在使用的时候是何时转换成invoker跟serviceBean交互的。然后这里我们注意到referenceBean实现类FactoryBean接口,然后关于factoryBean接口的使用可以参考: https://blog.csdn.net/u013185616/article/details/52335864。 大抵意思是说实现了factoryBean的接口的类,以后调这个getBean这个的时候(不懂这个方法的可以看看spring初始化的过程,大抵就是所有bean使用的入口),调用的实际是这个Bean的getObject接口,所以这就明白了,dubbo消费者的所有秘密都藏在了这个getObject方法中。
我们看下getObject方法
跟到get方法里面,发现get方法在父类ReferenceConfig里面
也很简单了,直接打开init方法。
然后看下checkDefault方法
主要就是初始化一下consumer变量,appendProperties方法以前讲过,从jvm运行变量里面取相应的值写到consumer里面。
然后init方法的很多都是初始化和校验的代码,跟serviceBean类似就不详细分析了,然后中间有个resolve那段的代码不知道干嘛的,也不管了,我们直接看最核心的东西,就是这个createProxy(map)
map的话,是所有前面相关变量的参数和参数值(具体就不细分析了,主要看核心代码),然后后面的代码我先分析了,就是生成一个consumerModel放到ApplicationModel里面,这个类里面有所有的provider和comsumer,具体干嘛用就不知道了。 serviceBean那边也有
然后我们打开createProxy
然后别的都不看了,都是一些url上的处理,主要看看refprotocol.refer(interfaceClass, url) 这段
可以看到这里用SPI又生成了一个dubboProtocol。然后我们打开dubboProtocol.refer方法:
我们看这里主要就是创建了一个dubboInvoker实例,然后我们看看dubboInvoker
主要看看doInboke方法,可以看到这里用入参是dubbo自己定义的RpcInvocation,返回接口是RpcResult对象。
我们看看RpcInvocation
可以看到这个是方法名,参数类型,具体参数全在这里了,说明真正需要徐序列化然后传送的就是这个RpcInvocation。
然后RpcResult
RpcResult也很简单,结果还有异常。也很明了了。
然后具体的怎么获取客户端,怎么调用网络连接这块我们就不看了,把主流程走一遍就行。
然后看createProxy方法的最后面,getProxy
然后spi默认的是JavassistProxyFactory,继续打开
然后看到getProxy就是典型JavassistProxy创建动态代理过程,然后看看InvokerInvocationHandler
这里可以看到代理实际执行的就是dubboInvoker的invoke方法,然后把方法和参数列表传送过去.
然后dubboInvoker负责实际网络通信找到暴露的exporter,然后执行实际的方法,并返回结果。然后具体负责均衡模块,跟注册中心交互的模块我们也先不看了。
他交互的具体原理,我觉得应该是通过dubboinvoker根据相同的interface 会找到对应的exporter,然后在exporter那边执行实际的逻辑。
当然实际的肯定复杂得多,我们就不关心了,估计我们也不会去改这些东西。
总结:
我们回头再来看,dubbo用到了哪些技术。首先,他自定义了spring标签的解析器,自定义了新的bean。然后在代码中用了SPI,动态代理,序列化等技术。网络层面用到了netty,同步非阻塞的网络io服务。比较适合小数据量,并发量高,消费者远大于提供者的场景。然后在分布式协调技术上使用了zookeer,zookeer相关: https://www.cnblogs.com/felixzh/p/5869212.html 。还有以及dubbo中所有类的层层封装和继承。封装和继承个人认为了解为主,毕竟如果真正需要自己去实现的话,可能业务也不一样,场景也不一样,所以定义出来的类和接口可能也会不一样,关键是把整个dubbo那些基础技术学会就行。如果让自己去写,也能写个基本的功能出来。
以上就是我所有阅读dubbo源码的过程,谢谢!