Dubbo与Spring的融合机制

 我来答
舒适还明净的海鸥i
2022-06-02 · TA获得超过1.7万个赞
知道小有建树答主
回答量:380
采纳率:0%
帮助的人:70.3万
展开全部

我们都知道Dubbo可以与Spring进行融合,那是怎么进行融合的呢?
我先介绍一下官方文档中是如何实现与Spring融合的,然后再从底层分析一下。

Service注解暴露服务

增加应用配置信息

指定Spring扫描路径

Reference注解引用服务

增加应用配置信息

指定Spring扫描路径

调用服务

上面是整体融合Spring的案例,接下来分析 Service 注解和 Reference 注解是怎么实现的。

当用户使用注解 @DubboComponentScan 时,会激活 DubboComponentScanRegister ,同时生成 ServiceAnnotationBeanPostProcessor 和 ReferenceAnnotationBeanPostProcessor , ServiceAnnotationBeanPostProcessor 处理器实现了 BeanDefinitionRegistryPostProcessor 接口,Spring容器会在所有Bean注册之后回调 postProcessBeanDefinitionRegistry 方法。
在这个方法里先提取用户配置的扫描包名称,然后委托Spring对所有符合包名的class文件做字节码分析,然后扫描Dubbo的注解@Service作为过滤条件,将扫描的服务创建 BeanDefinitionHolder ,用于生成 ServiceBean 定义,最后注册 ServiceBean 的定义并做数据绑定和解析。

这时我们注册了 ServiceBean 的定义,但是还没有实例化。
ServicecBean 的结构如下:

InitializingBean

只包含 afterPropertiesSet() 方法,继承该接口的类,在初始化Bean的时候会执行该方法。在构造方法之后调用。

ApplicationContextAware

Spring容器会检测容器中的所有Bean,如果发现某个Bean实现了 ApplicationContextAware 接口,Spring容器会在创建该Bean之后,自动调用该Bean的 setApplicationContextAware() 方法,调用该方法时,会将容器本身作为参数传给该方法。

ApplicationListener

当Spring容器初始化之后,会发布一个ContextRefreshedEvent事件,实现ApplicationListener接口的类,会调用 onApplicationEvent() 方法。

重要的接口主要是这几个,那么执行的先后顺序是怎样的呢?

如果某个类实现了ApplicationContextAware接口,会在类初始化完成后调用setApplicationContext()方法进行操作

首先会执行 ApplicationContextAware 中的 setApplicationContextAware() 方法。

这里主要是将Spring的上下文引用保存到 SpringExtensionFactory 中,里面有个set集合,保存所有的Spring上下文。这里实现了Dubbo与Spring容器的相连,在SPI机制中利用 ExtensionLoader.getExtension 生成扩展类时,会有一个依赖注入的过程,即调用 injectExtension() 方法,它会通过反射获取类的所有方法,然后遍历以set开头的方法,得到set方法的参数类型,再通过ExtensionFactory寻找参数类型相同的扩展类实例。

如果某个类实现了InitializingBean接口,会在类初始化完成后,并在setApplicationContext()方法执行完毕后,调用afterPropertiesSet()方法进行操作

然后会调用 InitializingBean 的 afterPropertiesSet() 方法。

主要是将Dubbo中的应用信息、注册信息、协议信息等设置到变量中。最后有个方法值得注意的是 isDelay 方法当返回true时,表示无需延迟导出;返回false时,表示需要延迟导出。

最后会调用 ApplicationListene 中的 onApplicationEvent 方法。

此时 ServiceBean 开始暴露。 具体的暴露流程之前已经介绍容量。

在Dubbo中处理 ReferenceBean 是通过 ReferenceAnnotionBeanPostProcessor 处理的,该类继承了 InstantiationAwareBeanPostProcessor ,用来解析@Reference注解并完成依赖注入。

InstatiationAwareBeanPostProcessor

postProcessBeforeInstantiation 方法: 在实例化目标对象执行之前,可以自定义实例化逻辑,如返回一个代理对象。

postProcessAfterInitialization 方法:Bean实例化完成后执行的后处理操作,所有初始化逻辑、装配逻辑之前执行。

postProcessPropertyValues 方法: 完成其他定制的一些依赖注入和依赖检查等,可以增加属性和属性值修改。

新版本出现了改动,采用 AnnotationInjectedBeanPostProcessor 来处理。

AnnotationInjectedBeanPostProcessor 是 ReferenceAnnotationBeanPostProcessor 的父类,它实现InstantiationAwareBeanPostProcessorAdapter的postProcessPropertyValues方法,这个是实例化的后置处理,这个方式是在注入属性时触发,就是要在注入@Reference的接口时候,要将接口封装成动态代理的实例注入到Spring容器中.

主要分为两步:
1) 获取类中标注的@Reference注解的字段和方法。
2)反射设置字段或方法对应的引用

最重要的是第二步,通过 inject 方法进行反射绑定。

里面最主要的就是对生成的ReferenceBean设置一个代理对象。

服务引用的触发时机有两个:
一种是ReferenceBean初始化的时候;另一种是ReferenceBean对应的服务被注入到其他类中时引用。

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式