当Provider将服务暴露之后,Consumer就可以通过注册中心进行引用,配置方式如下:
1 | <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
也可以使用注解@Reference:
1 | "demoServiceComponent") ( |
ReferenceBean
dubbo:reference对应ReferenceBean,ReferenceBean实现了FactoryBean和InitializingBean:
- ReferenceBean是一个FactoryBean,FactoryBean是Spring中的一个工厂bean,通过getObject得到bean对象。
- ReferenceBean实现了InitializingBean,同样是Spring中的一个类,通过afterPropertiesSet可以对bean进行初始化。
1 | public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, |
ReferenceConfig
ReferenceConfig是ReferenceBean的父类,获取bean的get方法中,对bean进行了判断,如果为空调用init方法进行初始化:
与Provider服务暴露流程一样,调用了 DubboBootstrap的init进行了初始化
调用createProxy创建代理对象:
(1)判断是本地JVM引用还是远程引用
(2)如果是远程引用,根据url判断是直连的方式还是从注册中心进行引用
(3)会根据具体的协议调用PROTOCOL的refer方法生成Invoker对象
(4)根据Invoker对象创建代理对象
1 | public class ReferenceConfig<T> extends ReferenceConfigBase<T> { |
Invoker的创建
Protocol使用ExtensionLoader来加载具体的扩展类:
1 | private static final Protocol REF_PROTOCOL = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension(); |
使用的是registry,因此将会进入RegistryProtocol的refer方法。
RegistryProtocol
doRefer方法中,会创建RegistryDirectory对象,并调用subscribe进行订阅:
1 | public class RegistryProtocol implements Protocol { |
RegistryDirectory
RegistryDirectory继承了NotifyListener,是一个监听器。
RegistryDirectory中实现了subscribe方法,可以看到它是通过调用Registry的subscribe实现的,Registry是一个接口,我们使用的是zookeeper注册中心,所以接下来进入ZookeeperRegistry:
1 | public class RegistryDirectory<T> extends AbstractDirectory<T> implements NotifyListener { |
ZookeeperRegistry
FailbackRegistry
subscribe方法在它的父类FailbackRegistry中实现:
1 | public abstract class FailbackRegistry extends AbstractRegistry { |
在ZookeeperRegistry的doSubscribe方法中,会创建ZK客户端,从注册中心进行订阅,订阅之后会调用notify方法通知:
1 | public class ZookeeperRegistry extends FailbackRegistry { |
FailbackRegistry中的notify方法实现:
1 | //org.apache.dubbo.registry.support.FailbackRegistry中的notify方法 |
由上可知,最终会调用NotifyListener的notify方法,前面的内容可知,NotifyListener传入的是RegistryDirectory对象,所以会进入到
RegistryDirectory的notify方法,在这个过程中比较关键的一步是toInvokers方法中将url转为Invoker:
1 | public class RegistryDirectory<T> extends AbstractDirectory<T> implements NotifyListener { |
DubboProtocol
接下来以DubboProtocal为例,进入refer方法中,refer在DubboProtocol的父类AbstractProtocol中实现:
- 调用了getClients创建客户端连接
- 创建了DubboInvoker
1 | public abstract class AbstractProtocol implements Protocol { |
1 | public class DubboProtocol extends AbstractProtocol { |
创建代理对象
在Invoker创建完毕之后,会通过PROXY_FACTORY创建代理对象:
1 | private static final ProxyFactory PROXY_FACTORY = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); |
在dubbo中默认使用Javassist创建代理对象:
1 | public class JavassistProxyFactory extends AbstractProxyFactory { |
InvokerInvocationHandler
1 | public class InvokerInvocationHandler implements InvocationHandler { |
参考
【休息的风】dubbo 源码学习笔记 (三) —— dubbo引用服务的过程
【峡谷程序猿】Dubbo2.7.6启动原理之Consumer
dubbo版本:2.7.7