• Dubbo(四):Spring 整合 Dubbo 源码分析


    Spring 与 Dubbo 整合

    回顾 Spring BeanDefinition

    在 Java 中,一切皆对象。

    在 JDK 中使用 java.lang.Class 来描述类这个对象。
    在 Spring 中,bean 对象是操作核心。那么 Spring 也需要一个东西来描述 bean 这个对象,它就是 BeanDefinition。

    spring 的基础流程,其整体类图如下:

    在这里插入图片描述
    在这里插入图片描述
    最后的 spring 动作 applicationContext.registerBeanDefinition 会在 IOC 容器内创建描述的 bean 对象

    Dubbo 的配置解析过程

    目标是把配置的属性值提取出来,变成 dubbo 的组件 bean

    • 先由 BeanDefinition 描述,再委托 Spring 生成组件 bean

    1. 架构

    在这里插入图片描述

    2. xml 配置的解析过程

    在这里插入图片描述
    在这里插入图片描述

    3. 注解的解析过程

    在这里插入图片描述

    在这里插入图片描述

    • @EnableDubboConfig 主要用于处理 dubbo 中全局性的组件配置, 一般在.properties 文件中的配置项,如 Application/Registry/Protocol/Provider/consumer
    • @DubboComponentScan 负责扫描项目源代码,处理业务类上的 Reference/Service 注解

    4. EnableDubboConfig – DubboConfigConfigurationRegistrar

    在这里插入图片描述

    • registerBeans(registry, DubboConfigConfiguration.Single.class);
    • registerBeans(registry, DubboConfigConfiguration.Multiple.class);
      在这里插入图片描述
    • @EnableDubboConfigBindings
      在这里插入图片描述
    • DubboConfigBindingsRegistrar.registerBeanDefinitions

    在这里插入图片描述

    • DubboConfigBindingRegistrar.registerDubboConfigBeans
      对Properties文件进行解析,根据Properties文件的每个配置项的前缀、参数名、参数值生成对应的BeanDefinition
      • registerDubboConfigBean(beanName, configClass, registry); // 为每个beanName,注册一个空的BeanDefinition
      • registerDubboConfigBindingBeanPostProcessor(prefix, beanName, multiple, registry); // 为每个bean注册一个DubboConfigBindingBeanPostProcessor的Bean后置处理器

    5. DubboComponentScan – DubboComponentScanRegistrar

    在这里插入图片描述

    5.1 registerServiceAnnotationBeanPostProcessor(packagesToScan, registry);

    在这里插入图片描述

    • 添加ServiceAnnotationBeanPostProcessor
    • ServiceAnnotationBeanPostProcessor.postProcessBeanDefinitionRegistry
    • ServiceAnnotationBeanPostProcessor.registerServiceBeans(resolvedPackagesToScan, registry); // 扫描包,进行Bean注册
    • scanner.addIncludeFilter(new AnnotationTypeFilter(Service.class)); // 扫描被Service注解标注的类
    • ServiceAnnotationBeanPostProcessor.registerServiceBean(beanDefinitionHolder, registry, scanner); // 扫描到BeanDefinition开始处理它
    • ServiceAnnotationBeanPostProcessor.buildServiceBeanDefinition(service, serviceAnnotationAttributes, interfaceClass, annotatedServiceBeanName); // 生成一个ServiceBean

    在这里插入图片描述

    • ServiceBean implements ApplicationListener
    • ServiceBean.onApplicationEvent //当前服务没有被导出并且没有卸载,才导出服务
      • export(); // 服务导出(服务注册)

    5.2 registerReferenceAnnotationBeanPostProcessor(registry);

    在这里插入图片描述

    • BeanRegistrar.registerInfrastructureBean(registry, ReferenceAnnotationBeanPostProcessor.BEAN_NAME, ReferenceAnnotationBeanPostProcessor.class);
      - Register @Reference Annotation Bean Processor
      - 注册一个ReferenceAnnotationBeanPostProcessor做为bean, ReferenceAnnotationBeanPostProcessor是一个BeanPostProcessor

    • ReferenceAnnotationBeanPostProcessor.class

    • ReferenceAnnotationBeanPostProcessor.doGetInjectedBean // 该方法得到的对象会赋值给@ReferenceBean注解的属性

      • AnnotationInjectedBeanPostProcessor.postProcessPropertyValues
      • InjectionMetadata metadata = findInjectionMetadata(beanName, bean.getClass(), pvs); // 寻找需要注入的属性(被@Reference标注的Field)
        • Collection fieldElements = findFieldAnnotationMetadata(beanClass); // 哪些Filed上有@Reference注解
        • Collection methodElements = findAnnotatedMethodMetadata(beanClass); // 哪些方法上有@Reference注解
      • metadata.inject(bean, beanName, pvs);
      • AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement.inject & AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement.inject
      • AnnotationInjectedBeanPostProcessor.getInjectedObject()
      • ReferenceAnnotationBeanPostProcessor.doGetInjectedBean
    ReferenceAnnotationBeanPostProcessor.doGetInjectedBean

    在这里插入图片描述
    代理对象
    在这里插入图片描述

    • ReferenceBean
      • get()
        在这里插入图片描述
      • init()

    在这里插入图片描述

    • ReferenceBean implements FactoryBean
      @Override
      public Object getObject() {
          return get();
      }
      
      • 1
      • 2
      • 3
      • 4

    ReferenceBean的get()方法得到一个代理对象

  • 相关阅读:
    【Linux操作系统】crontab设置自动运行脚本
    jmeter+influxdb+grafana实时监控平台详细教程
    Arduino与Proteus仿真-Nokia5110 LCD界面菜单仿真
    租服务器训练深度学习模型
    echarts 类目轴设置xAxis.interval不起效果
    使用Tomcat搭建一个Servlet项目
    VueRouter的使用
    Web前端开发PDF:技术与挑战的深度剖析
    ElasticSearch 之 文本搜索
    高并下如何做变量的自增与自减
  • 原文地址:https://blog.csdn.net/menxu_work/article/details/126418487