zoukankan      html  css  js  c++  java
  • dubbo源码分析(一)-从xml到我们认识的Java对象

      项目中用的dubbo的挺多的,然后随着自己对dubbo的慢慢深入,自己也希望能够了解dubbo的底层实现,这半年来一直在看dubbo的源码,有点断断续续的,于是准备写一个dubbo源码系列的分析文章,一来方便自己总结,二来也能够让自己的学习有输出分享。
      整个系列会从dubbo的xml到bean到生产者启动-注册到消费者订阅-调用的这一主线,然后会穿插一些相关的负载均衡、熔断、过滤器、监控、spi等等。让我们进入一个全新的世界吧,let's go
      1、如果你好奇为什么配置了xml文件dubbo就可以启动,dubbo的配置文件如何转换为我们的Java中的对象的?
      2、想对spring中的自定义的标签有所了解的。
      那么本文特别适合你阅读。
        首先,我们来看一下简单的dubbo的provide的配置文件,如下:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4 xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
     5 xsi:schemaLocation="http://www.springframework.org/schema/beans 
     6 http://www.springframework.org/schema/beans/spring-beans.xsd 
     7 http://code.alibabatech.com/schema/dubbo 
     8 http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
     9 <!-- 提供方应用信息,用于计算依赖关系 -->
    10 <dubbo:application name="demo-provider"/>
    11 <!-- 使用zk广播注册中心暴露服务地址 -->
    12 <dubbo:registry id="zk1" address="127.0.0.1:2181" protocol="zookeeper"/>
    13 <!-- 用dubbo协议在20880端口暴露服务 -->
    14 <dubbo:protocol id="mydubbo" name="dubbo" port="20880"/>
    15 <!-- 声明需要暴露的服务接口 -->
    16 <dubbo:service interface="com.dubbo.DemoService" ref="demoService"/>
    17 </beans>

      刚开始看的时候,我就很好奇dubbo怎么识别这些,之前对spring的自定义标签有一些了解,http://code.alibabatech.com/schema/dubbo,http://code.alibabatech.com/schema/dubbo/dubbo.xsd 这2行有一点吸引我们,打开看看发现里面定义了dubbo相关标签的xsd,对于xsd不了解的同学自己查资料学习了哈,这里不在做解释。找到xsd文件我们就知道要到spring.handlers文件看看,打开这个文件看看:

    1 http://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler

    发现猫腻了,这里定义了http://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler,其实这是一个键值对,那我们就看看DubboNamespaceHandler是干嘛的:

    public class DubboNamespaceHandler extends NamespaceHandlerSupport {
    
      static {
        Version.checkDuplicate(DubboNamespaceHandler.class);
      }
    
      public void init() {
        registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
        registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
        registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
        registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
        registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
        registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
        registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
        registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
        registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
        registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));
      }
    }

      发现我们熟悉的dubbo标签都在这里,看名字registerBeanDefinitionParser就知道是注册bean的解析了,原来dubbo的每个标签都对应一个class,可以打开每个class看看,发现都是每个标签的属性以及一些相关的处理,这里就不在打开了,有init方法,应该是加载的时候调用init,到这里可能就好奇了这个类是什么时候加载的呢?联想到spring.handlers里面的东西,好像好多spring相关的都会有这么一个东西,那我们找找spring怎么加载解析spring.handlers的,我这里基于大家都比较熟悉spring的bean加载过程了哈。
      直接定位到org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitions方法:根据root解析节点

      1-2、判断是不是默认的namespace;
      3、不是默认namespace就parseCustomElement解析节点;
      4、获取namspaceUri,根据namspaceUri去获取namespaceHandler,然后利用handler解析dubbo节点。

      1、获取解析的节点的localname;
      2、根据localname去找BeanDefinitionParser,找到BeanDefinitionParser并返回。
      我在网上找到这么一个图,显示了加载的和解析的过程。

  • 相关阅读:
    Java面向对象_常用类库api——二分查找算法
    Spyder中代码提示功能添加
    随机数种子random.seed()理解
    Windows10下Anaconda+Tensorflow+Keras环境配置
    面向对象分析与设计—OOD部分
    面向对象分析与设计—OOA部分
    面向对象分析与设计—基本概念部分
    基于聚类K-Means方法实现图像分割
    机器学习中强化学习与监督学习、无监督学习区别
    LeetCode501.二叉搜索树中的众数
  • 原文地址:https://www.cnblogs.com/liaoweipeng/p/10193788.html
Copyright © 2011-2022 走看看