Dubbo源码分析:dubbo与spring融合

概述

  • Dubbo框架主要是用于分布式系统中服务之间的远程调用。而分布式系统中的每个服务一般为采用spring框架搭建,通过spring容器管理beans,通过spring mvc提供restful接口,在service层进行业务逻辑处理。而不管是服务消费者引用的bean,还是服务提供者需要对外提供服务、进行注册的bean,都需要一种机制来触发其进行初始化,生成JVM堆的一个对象实例,同时由spring容器管理,可以通过@Autowired进行注入,从而可以在运行时进行调用。
  • 在dubbo源码结构中,主要在dubbo-config模块进行服务建模。具体为在dubbo-config-api子模块对服务进行各粒度的建模,依次为应用、提供者、消费者、注册中心、服务模块、服务提供类和引用类、方法、方法参数;在dubbo-config-spring子模块将消费者配置引用的服务,提供者配置对外提供调用的服务分别融合到相应项目的spring容器中,从而可以在service层通过@Autowired的机制进行注入。
    在这里插入图片描述

配置解析规则定义

  1. 在dubbo.xsd定义dubbo相关标签
    在这里插入图片描述
  2. 在dubbo.schemas定义标签的位置location
    在这里插入图片描述
  3. dubbo标签处理器器配置:在spring.handlers中定义了dubbo的命名空间和标签处理器DubboNamespaceHandler的对应关系,即当遇到dubbo标签的时候,使用DubboNamespaceHandler进行处理,解析生成beanDefinition,其中DubboNamespaceHandler继承于NamespaceHandlerSupport。
    在这里插入图片描述
    在这里插入图片描述

解析配置文件并生成beanDefinition

在spring扫描和解析xml文件遇到dubbo标签的时候,会使用DubboNamespaceHandler进行标签处理。

  1. DubboNamespaceHandler:自定义了BubboBeanDefinitionParser,使用相应的解析器,解析配置文件的标签,并转换成相应的beanDefinition。
    在这里插入图片描述
    在这里插入图片描述
  2. 通过registerBeanDefinitionParser将标签名称和解析器的对应关系注册到NamespaceHandlerSupport中的parsers中,从而在spring扫描和解析xml文件遇到对应的dubbo标签时,会使用相应的DubboBeanDefinitionParser进行标签解析,生成beanDefinition。通过registerBeanDefinitionParser将标签名称和解析器的对应关系注册到NamespaceHandlerSupport中的parsers中,从而在spring扫描和解析xml文件遇到对应的dubbo标签时,会使用相应的DubboBeanDefinitionParser进行标签解析,生成beanDefinition。
    在这里插入图片描述
    如果是使用注解而不是配置文件,则使用AnnotationBeanDefinitionParser。
    在这里插入图片描述

服务提供者提供的服务Service:ServiceBean

在这里插入图片描述

  1. ServiceBean实现ApplicationListener接口,泛型参数为ContextRefreshedEvent,从而在spring容器启动或重启时会触发。
    在这里插入图片描述
  2. ServiceBean继承于ServiceConfig,调用ServiceConfig的export方法,该方法会产生该service的Invoker,即通过该Invoker调用serviceImpl的方法,其中invoker是从该service的具体实现代理ref获取:
    在这里插入图片描述
    包含setRef方法,通过ExtensionLoader注入。
    在这里插入图片描述
  3. 由之前的文章分析可知,export最终会调用RegistryProtocol的export方法完成服务导出,注册到注册中心,同时会调用doLocalExport,在提供者本地生成消费者请求处理invoker。具体为根据URL确定所使用的、对应与dubbo-rpc模块的具体rpc协议protocol,如DubboProtocol,调用protocol.export创建export对象和实际的监听URL和请求处理器,DubboProtocol请求处理器的远程通讯由dubbo-remoting模块实现,源码如下:
    在这里插入图片描述
    在这里插入图片描述
    其中invoker为2中,注册导出服务时创建的invoker。

服务消费者引用的服务Reference:ReferenceBean

在这里插入图片描述

  1. 在解析dubbo:reference时,会产生ReferenceBean的实例。ReferenceBean实现了spring的FactoryBean接口,故spring在注入bean时,在程序使用如@Autowired时,会调用getObject方法,获取对象实例,如果是singleton类,则放到spring单实例缓存池。
  2. ReferenceBean继承于ReferenceConfig,getObject调用ReferenceConfig的get方法,其中get为使用synchronized修饰,保证只初始化一次:
    在这里插入图片描述
    init方法底层实现核心源码如下:
    在这里插入图片描述
    其中map为该对象实例的属性和属性值,通过createProxy创建消费者调用的代理对象。createProxy的核心源码实现如下:
    (1)refprotocol:根据URL的protocol获取到dubbo-rpc模块的protocol实现,调用refprotocol.refer获取对应的消费者端的调用;通过这个代理来对服务提供者或者说服务端发起RPC请求;
    (2)cluster.join:如果包含多个注册中心,则调用cluster.join进行负载均衡获取一个调用;
    (3)proxyFactory.getProxy(invoker):获取最终的消费者调用代理,代理提供了一个模板,最终的调用逻辑是定义在对应的Invoker的doInvoke方法,如DubboInvoker,在doInvoker中再调用dubbo-remoting模块的client进行远程通讯。
    在这里插入图片描述

DubboBootstrap注册spring shutdownHook

这个是在dubbo被apache孵化后,加入的。包括注册spring shutdownhook和export Service,但是export Service目前没有具体实现,还是在注册ServiceBean创建bean实例时,export。

  1. 通过context-param的方式将dubbo引入到宿主应用中
    web-fragment.xml文件:相当于web.xml的一个小片段,通过合并这个文件到web.xml,从而在宿主应用启动时,初始化DubboApplicationContextInitializer。
    在这里插入图片描述

  2. 监听spring框架启动:在DubboApplicationContextInitializer初始化时,将DubboApplicationListener作为监听器,监听宿主应用的启动。
    在这里插入图片描述
    DubboApplicationListener监听宿主应用的启动和关闭,调用DubboBootstrap进行dubbo框架的启动和关闭。
    在这里插入图片描述

    /**

    • A bootstrap class to easily start and stop Dubbo via programmatic API.

    • The bootstrap class will be responsible to cleanup the resources during stop.
      */
      public class DubboBootstrap
      核心方法
      public void start() {
      if (registerShutdownHookOnStart) {
      registerShutdownHook();
      } else {
      // DubboShutdown hook has been registered in AbstractConfig,
      // we need to remove it explicitly
      removeShutdownHook();
      }
      for (ServiceConfig serviceConfig: serviceConfigList) {
      serviceConfig.export();
      }
      }

      public void stop() {
      for (ServiceConfig serviceConfig: serviceConfigList) {
      serviceConfig.unexport();
      }
      shutdownHook.destroyAll();
      if (registerShutdownHookOnStart) {
      removeShutdownHook();
      }
      }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值