开启成长之旅!这是我参与「日新方案 12 月更文应战」的第15天,点击检查活动详情

开篇

本文对Dubbo与Spring整合原理整个进程做一个总结。

一、Dubbo与Spring整合原理—装备解析

二、Dubbo与Spring整合原理——@DubboService解析

三、Dubbo与Spring整合原理—@DubboReference

Dubbo与Spring整合在启动进程中,需求经历3个主要的步骤:

  1. 解析装备文件
  2. 解析@DubboService注解
  3. 解析@DubboReference注解
@Configuration
@EnableDubbo(scanBasePackages = "org.apache.dubbo.demo.provider") 
@PropertySource("classpath:/spring/dubbo-provider.properties") 
public class ProviderConfiguration { 
    @Bean 
    public RegistryConfig registryConfig() { 
        RegistryConfig registryConfig = new RegistryConfig(); 
        registryConfig.setAddress("zookeeper://127.0.0.1:2181"); 
        return registryConfig; 
    } 
}

解析装备文件

加载装备文件是由@PropertySource注解将properties的装备加载解析放入environment目标中。

解析Dubbo相关的装备是由@EnableDubboConfig负责的,@EnableDubboConfig导入了一个类DubboConfigConfigurationRegistrar,这个类将Dubbo的装备规则和装备类进行一一绑定。无论是单项装备仍是多个装备,对应的装备类是相同的,对应关系如下:

Dubbo源码|十一、Dubbo与Spring整合原理总结

单个解析示例:

dubbo.application.name=dubbo-demo-provider-application

此装备前缀为dubbo.application,会生成一个ApplicationConfig类型的BeanDefinition,其name的特点值为dubbo-demo-provider-application

多个解析示例:

dubbo.protocols.first.name=dubbo
dubbo.protocols.first.port=20880
dubbo.protocols.second.name=dubbo
dubbo.protocols.second.port=20881

此装备前缀为dubbo.protocols,他会生成两个ProtocolConfig类型的BeanDefinition,他们的beanName分别为firstsecond

解析装备文件主要进程如下:

  1. 读取properties或yml装备文件,将装备解析为key-value形式,并放入environment目标中。
  2. 解析DubboConfigConfiguration.Single注解,处理注解上装备prefix与装备类的关系。
  3. 解析DubboConfigConfiguration.Multiple注解,处理注解上装备prefix与装备类的关系。
  4. 解析上述注解后,将获取到的注解进行遍历,依据multiple特点分类处理。
  5. 获取装备prefix对应的一切装备特点值(从environment目标中获取)。
  6. properties或yml装备生成对应的Bean
  7. 注册BeanPOSTProcessor处理特点值。

下面是讲装备文件的解析进程用流程图表明:

Dubbo源码|十一、Dubbo与Spring整合原理总结

解析@DubboService

@DubboService注解表明这个类归于一个Dubbo服务,解分出服务进行服务导出,并供给服务。

解析@DubboService的主要逻辑如下:

  1. 注册一个ServiceClassPostProcessor
  2. 获取扫描途径,对扫描途径进行扫描
  3. 获取哪些类上标有@DubboService注解
  4. 解析含有@DubboService注解的类,生成对应的BeanDefinition
  5. 依据@DubboService装备进行赋值并进行注册

@DubboService解析后会生成两个Bean,一个是Spring的普通Bean,一个是归于Dubbo服务的ServiceBean

ServiceBean表明一个Dubbo服务,它内部含有一些重要的参数,例如:

  1. interface,表明Dubbo服务的接口
  2. parameters,服务参数包括DubboService注解的信息。
  3. application,表明这个服务所归属的使用。
  4. protocols,表明服务所使用的协议,Dubbo服务或许有多个协议。
  5. registries,表明服务所要注册的注册中心,注册中心也或许包括多个。
  6. ref,表明服务的具体完成类,其特点值为Spring容器的一个Bean

Dubbo源码|十一、Dubbo与Spring整合原理总结

解析@DubboReference

@DubboReference注解标示的特点,代表要引进一个服务,代表一个注入点。@DubboReference注解是由ReferenceAnnotationBeanPostProcessor类来处理的。

Spring在进行依靠注入时,是调用AbstractAnnotationBeanPostProcessor类的postProcessPropertyValues方法来为特点赋值。

在Spring进行赋值操作时,需求先获取一个目标,这个目标便是ReferenceAnnotationBeanPostProcessor类的doGetInjectedBean的方法来获取一个目标,这个目标是一个署理目标。

在生成这个署理目标时,需求判别:

  1. 要引进的这个Dubbo服务是否为本地服务,不是的话就依照Dubbo的逻辑生成一个署理目标。
  2. 要引进的这个Dubbo服务是否被引进过了,假如现已引进过了,就直接拿来用不需求重复生成了。

如何判别当前所引进的服务是本地的一个服务?

咱们知道在生成ServiceBean的时候,beanName的生成规则为接口类型+group+version。而在生成referencedBeanName的时候,生成的规则和ServiceBeanbeanName是共同的,所以进行对比一下,假如是共同的直接调用ReferenceBean.get就可以了。

如何判别当前所引进的这个服务是否现已被引进过了呢?

首要依据@DubboReference注解的一切信息+特点接口类型生成一个字符串作为beanName,去Spring容器查找是否有对应的缓存,假如没有的话,则把ReferenceBean目标作为bean放到Spring容器中。

@DubboReference目标示入流程如下

Dubbo源码|十一、Dubbo与Spring整合原理总结

后记

关于Dubbo与Spring整合流程这儿就基本介绍完了,后面会介绍Dubbo服务导出以及引进的具体进程。