开启成长之旅!这是我参与「日新方案 12 月更文应战」的第15天,点击检查活动详情
开篇
本文对Dubbo与Spring整合原理整个进程做一个总结。
一、Dubbo与Spring整合原理—装备解析
二、Dubbo与Spring整合原理——@DubboService解析
三、Dubbo与Spring整合原理—@DubboReference
Dubbo与Spring整合在启动进程中,需求经历3个主要的步骤:
- 解析装备文件
- 解析@DubboService注解
- 解析@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.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
分别为first
、second
。
解析装备文件主要进程如下:
- 读取
properties或yml
装备文件,将装备解析为key-value形式,并放入environment目标中。 - 解析
DubboConfigConfiguration.Single
注解,处理注解上装备prefix与装备类的关系。 - 解析
DubboConfigConfiguration.Multiple
注解,处理注解上装备prefix与装备类的关系。 - 解析上述注解后,将获取到的注解进行遍历,依据
multiple
特点分类处理。 - 获取装备
prefix
对应的一切装备特点值(从environment
目标中获取)。 - 将
properties或yml
装备生成对应的Bean
。 - 注册
BeanPOSTProcessor
处理特点值。
下面是讲装备文件的解析进程用流程图表明:
解析@DubboService
@DubboService
注解表明这个类归于一个Dubbo
服务,解分出服务进行服务导出,并供给服务。
解析@DubboService
的主要逻辑如下:
- 注册一个
ServiceClassPostProcessor
- 获取扫描途径,对扫描途径进行扫描
- 获取哪些类上标有
@DubboService
注解 - 解析含有
@DubboService
注解的类,生成对应的BeanDefinition
- 依据
@DubboService
装备进行赋值并进行注册
@DubboService
解析后会生成两个Bean
,一个是Spring
的普通Bean
,一个是归于Dubbo服务的ServiceBean
。
ServiceBean
表明一个Dubbo服务,它内部含有一些重要的参数,例如:
-
interface
,表明Dubbo
服务的接口。 -
parameters
,服务参数包括DubboService
注解的信息。 -
application
,表明这个服务所归属的使用。 -
protocols
,表明服务所使用的协议,Dubbo服务或许有多个协议。 -
registries
,表明服务所要注册的注册中心,注册中心也或许包括多个。 -
ref
,表明服务的具体完成类,其特点值为Spring
容器的一个Bean
。
解析@DubboReference
被@DubboReference
注解标示的特点,代表要引进一个服务,代表一个注入点。@DubboReference
注解是由ReferenceAnnotationBeanPostProcessor
类来处理的。
Spring在进行依靠注入时,是调用AbstractAnnotationBeanPostProcessor
类的postProcessPropertyValues
方法来为特点赋值。
在Spring进行赋值操作时,需求先获取一个目标,这个目标便是ReferenceAnnotationBeanPostProcessor
类的doGetInjectedBean
的方法来获取一个目标,这个目标是一个署理目标。
在生成这个署理目标时,需求判别:
- 要引进的这个Dubbo服务是否为本地服务,不是的话就依照Dubbo的逻辑生成一个署理目标。
- 要引进的这个Dubbo服务是否被引进过了,假如现已引进过了,就直接拿来用不需求重复生成了。
如何判别当前所引进的服务是本地的一个服务?
咱们知道在生成ServiceBean
的时候,beanName
的生成规则为接口类型+group+version
。而在生成referencedBeanName
的时候,生成的规则和ServiceBean
的beanName
是共同的,所以进行对比一下,假如是共同的直接调用ReferenceBean.get就可以了。
如何判别当前所引进的这个服务是否现已被引进过了呢?
首要依据@DubboReference
注解的一切信息+特点接口类型生成一个字符串作为beanName
,去Spring容器查找是否有对应的缓存,假如没有的话,则把ReferenceBean
目标作为bean放到Spring容器中。
@DubboReference目标示入流程如下
后记
关于Dubbo与Spring整合流程这儿就基本介绍完了,后面会介绍Dubbo服务导出以及引进的具体进程。