• 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()方法得到一个代理对象

  • 相关阅读:
    Java通过Lambda表达式根据指定字段去除重复数据(集合去重)
    【已解决】windows10误删环境变量Path
    『现学现忘』Docker基础 — 22、使用Docker安装Nginx
    IPKISS Tutorials 3------绘制矩形版图
    Windchill 11文件夹选择组件使用记
    vue项目中设置background: url() 是行内样式不生效,样式表是可以的
    阿里云高工双管齐下!K8S+Docker理论与实践深度集成
    如何制作专属的VS Code主题
    人人都会Kubernetes(二):使用KRM实现快速部署服务,并且通过域名发布
    字符串——Trie
  • 原文地址:https://blog.csdn.net/menxu_work/article/details/126418487