dubbo如何利用spring扩展点完成初始化

本文详细探讨了Dubbo如何利用Spring的扩展点,包括@DubboComponentScan、DubboComponentScanRegistrar、ServiceAnnotationBeanPostProcessor和ReferenceAnnotationBeanPostProcessor,来完成服务的初始化。在初始化过程中,@Service注解的类被扫描并加入到Spring容器,而@Reference注解则在Bean初始化时处理,从Zookeeper拉取服务提供者并生成代理对象注入到目标Bean中。

dubbo在初始化的时候,充分利用了spring的扩展点,进行初始化,这篇笔记主要记录dubbo是如何利用spring的扩展点来进行初始化的;
这篇笔记只记录dubbo启动的时候的源码,不记录启动过程中服务导出和服务引入的源码

dubbo关键类

@DubboComponentScan
DubboComponentScanRegistrar
ServiceAnnotationBeanPostProcessor
ReferenceAnnotationBeanPostProcessor
ServiceBean
ReferenceBean
@Service
@Reference

dubbo在进行服务导出和服务引入之前,需要将对应的bean放入到spring容器中,比如:当前在UserService中引入了一个TestService,同时对外提供了一个OrderService的类
那dubbo在启动的时候,会扫描将加了@Service的OrderService先注入到spring的容器中,在spring容器启动完成之后,再去zk进行服务注册
同理在初始化UserService的时候,会对@Reference修饰的变量 TestService进行注入,注入的时候,就会去zk拉取对应的服务提供者,然后生成代理对象,将代理对象注入到UserService中

结论

1.在@DubboComponentScan注解中会import一个DubboComponentScanRegistrar,这个DubboComponentScanRegistrar是ImportBeanDefinitionRegistry的实现类
2.在其registerBeanDefinitions方法中会注入两个bean:ReferenceAnnotationBeanPostProcessor和ServiceAnnotationBeanPostProcessor

3.ServiceAnnotationBeanPostProcessor是BeanDefinitionRegistryPostProcessor的实现类,所以在其postProcessorBeanDefinitionRegistry()方法中,会调用dubboClassPathBeanDefinitionScanner的scan方法,进行扫描,将加了@Service注解的bean扫描到beanDefinitionMap中
添加到beanDefinitionMap中的时候,有一个点需要特别注意的是:对于dubbo的@Service注解所修饰的bean,在spring的beanDefinitionMap中,会有两个会beanDefinition,一个是正常的beanDefinition,可以理解为和spring扫描的bean是无差别的,另外一个beanDefinition的beanClass被设置为ServiceBean,这个我觉得和Mybatis的接口在被注入到beanDefinitionMap中的时候有点类似
在初始化bean的时候,如果整个spring容器刷新完成了,serviceBean会监听对应的事件,在监听到之后,开始进行服务导出的处理,这时候,调用的就是dubbo中的代码,完成:在zk中注册服务、开启netty等

3.ReferenceAnnotationBeanPostProcessor是一个后置处理器,会对加了@Reference注解的bean进行处理,如果A这个类中通过@Reference注入了bean,在注入的时候,会被这个后置处理器处理
在一个bean初始化的过程中,会进行属性注入,调用其inject方法,然后在inject方法中,会对要注入的bean进行处理,将referenceClass,也就是要注入的bean,包装成referenceBean,然后调用referenceBean的getObject()方法进行服务引入,在referenceBean.getObject()方法中,返回的是一个代理对象,在其getObject()方法中,会开启完成服务引入,然后在属性注入的时候,注入的就是一个代理对象

源码

@DubboComponentScan

这个注解如果陌生的话,那@EnableDubbo这个注解应该不会陌生

@EnableDubboConfig
@DubboComponentScan
public @interface EnableDubbo {
   
   
}

我们就直接来看@DubboComponentScan这个注解了

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(DubboComponentScanRegistrar.class)
public @interface DubboComponentScan {
   
   
}
DubboComponentScanRegistrar

可以看到,在其注解上,通过@Import注解,引入了这个类,这个类是ImportBeanDefinitionRegistrar的实现类,关于ImportBeanDefinitionRegistrar这个扩展点,在前面@Import原理
中有介绍过,这个也是spring的扩展点之一,在初始化的过程中,会调用ImportBeanDefinitionRegistrar实现类的registerBeanDefinitions()方法,

@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
   
   

    Set<String> packagesToScan = getPackagesToScan(importingClassMetadata);

    reg
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值