全局入口 spring schema handler
spring handler:com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler,定义了不同元素的解析器与映射的类。比如dubbo:reference对应ReferenceBean,dubbo:service对应ServiceBean。
provider侧
- 读取spring配置,dubbo会将spring xml中的dubbo:service元素通过预先定义好的解析器封装成一个ServiceBean,这是一个service的入口。
- ServiceBean实现了spring的ApplicationListener接口,用来监听spring上下文事件。Dubbo响应了ContextRefreshedEvent事件,在上下文刷新之后执行导出provider动作。
- 执行导出操作,需要两个信息:
- 通信协议信息,用来指定consumer和provider间的通信方式以及信息。
- 注册中心信息,用来往对应的注册中心注册provider url。
- com.alibaba.dubbo.config.ServiceConfig#doExportUrls生成registry URL以及provider URL,并将provider URL作为registry URL的export参数绑定。根据registry URL的协议registry://拿到对应的RegistryProtocol并调用其export方法。
- com.alibaba.dubbo.registry.integration.RegistryProtocol#export主要完成两件事情:
- 作为provider,使用定义好的通信协议来暴露服务,如dubbo,http,rmi等。
- 从registry URL的export参数来获取provider URL。
- 通过provider URL的协议来获取其对应的协议处理类并调用export方法。
- 使用registry URL中的registry参数作为注册中心协议替换原来的registry://协议
- 通过新的registry URL的协议头,拿到相应的com.alibaba.dubbo.registry.Registry实例并调用其com.alibaba.dubbo.registry.RegistryService#register方法,比如向zookeeper新建临时节点。
- 作为provider,使用定义好的通信协议来暴露服务,如dubbo,http,rmi等。
- 以上,就是provider侧的执行流程简述。
consumer侧
- 同样的,dubbo会将dubbo:reference封装成一个ReferenceBean,但与provider不同,consumer实现了org.springframework.beans.factory.FactoryBean接口,初始化的流程推迟到了调用org.springframework.beans.factory.FactoryBean#getObject时。
- 生成registry URL,暂时指定协议为registry://,并将实际协议作为registry参数的值绑定在URL上。
- 通过registry URL的协议registry://,得到相应RegistryProtocol,然后调用其com.alibaba.dubbo.registry.integration.RegistryProtocol#refer方法来获取provider引用。
- 更新registry URL协议。
- 通过registry URL获取相应的com.alibaba.dubbo.registry.Registry。
- com.alibaba.dubbo.registry.integration.RegistryDirectory。
- RegistryDirectory通过registry URL和接口类型生成和命名。
- RegistryDirectory用来封装所有的invoker地址信息以及路由信息等。
- 负责通过provider URL中的协议信息获取相应的链接协议处理类并调用refer()方法以获取Invoker对象。
- 生成订阅URL,协议为consumer://,通过registry URL获取相应的注册中心,向注册中心注册consumer URL。
- 调用对应的注册中心的subscribe方法,com.alibaba.dubbo.registry.RegistryService#subscribe。
- 通过调用com.alibaba.dubbo.registry.integration.RegistryDirectory#notify,最终会将provider URL保存到相应的RegistryDirectory中。
- 可以查看com.alibaba.dubbo.registry.zookeeper.ZookeeperRegistry#doSubscribe。
请求调用
- 默认使用JDK动态代理模式来获取实际执行类。
- 实际执行对象则是com.alibaba.dubbo.registry.integration.RegistryProtocol#refer返回的Invoker对象。
- 最终会执行com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker#invoke方法。
- 从RegistryDirectory中获取Invoker List。
- 通过负载均衡从Invoker List中获取一个Invoker。
-
拿到对应的链接协议Invoker实例,执行远程调用。
- 注意,consumer实例是由com.alibaba.dubbo.registry.integration.RegistryProtocol#refer生成的,而用来执行远程链接处理远程协议的refer()方法则是由RegistryDirectory负责调用的。