@EnableDubbo注解中有两个注解
@EnableDubboConfig是用来解析配置文件的
@DubboComponentScan是用来扫描@Service和@Refrence的
1.Dubbo中propertie⽂件解析以及处理原理
我们看到引入了DubboConfigConfigurationRegistrar,一看就知道干嘛了,老套路
我们看下DubboConfigConfiguration.Single
org.apache.dubbo.config.spring.context.annotation.DubboConfigBindingRegistrar#registerDubboConfigBeans
注册我们注解上ApplicationConfig、ProtocolConfig、ConfigCenterBean这些类的BeanDefinition
接下为每个AbstracetConfig bean注册一个DubboConfigBindingBeanPostProcessor的Bean后置处理器
org.apache.dubbo.config.spring.context.annotation.DubboConfigBindingRegistrar#registerDubboConfigBindingBeanPostProcessor
可以看到把我们的beanName作为构造参数传入
我们看下 DubboConfigBindingBeanPostProcessor
在afterPropertiesSet中初始化我们dubboConfigBinder,属性赋值用
每个XxConfig对应一个BeanPostProcessor,所以每个DubboConfigBindingBeanPostProcessor只处理对应的beanName
进行属性赋值
这样我们的XXXConfig 就已经又了配置文件中的值
注册了两个后置处理器,分别处理我们这两个注解
org.apache.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor
org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor
2.Dubbo中@Service注解解析以及处理原理
老朋友了,和mybatis套路一样
org.apache.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor#registerServiceBeans
首先和mybatis一样 也是定义了DubboClassPathBeanDefinitionScanner,设置useDefaultFilters = false,这样就不会扫描Component
然后把@Service 加入includeFilters,这样就可以扫描标记@Service注解的bean了
我们分别看下
1.
org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#findCandidateComponents
org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#isCandidateComponent(org.springframework.core.type.classreading.MetadataReader)
@Service 注解就会背扫描成BeanDefinition
但是此时他只是一个普通的springBean,并不能表示dubbo服务,所以dubbo还会为每一个springBean构建一个ServiceBean 表示 dubbo 提供者服务
2.
设置一些属性信息,例如ref指向springBean、interface指向属于哪个接口
ServiceBean继承了ServiceConfig,ServiceConfig封装了我们提供者的一些属性
然后给我们的@ServiceBean 起一个bean名称,接下来注册bean定义
bean名称就是ServiceBean常量+接口+组+版本等
3.Dubbo中@Reference注解解析以及处理原理
@Reference 可以标注在字段上用来属性注入
我们知道@Autowired是通过
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
注入的,他有一个父类
InstantiationAwareBeanPostProcessorAdapter
我们上面说到 注册了
org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor
可以看到我们注册的bean 也实现了InstantiationAwareBeanPostProcessorAdapter
Spring在对Bean进⾏依赖注⼊时会调⽤AnnotationInjectedBeanPostProcessor的 postProcessPropertyValues()⽅法来给某个Bean按照ReferenceAnnotationBeanPostProcessor的逻 辑进⾏依赖注⼊。
首先去找属性值,返回InjectionMetadata
我们这里返回的是AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata
接下来调用InjectionMetadata的inject方法
AnnotatedMethodElement重写inject方法
逻辑就是从spring 容器中拿出来,然后反射放进去
我们重点看下怎么从spring拿的
org.apache.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#getInjectedObject
其余部分是缓存,重点看下org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#doGetInjectedBean
六个方法,我们分别看下
1.第一步就是拿@Service的bean名称
2.第二步就是拿@Refrence的bean名称
3.第三步构建ReferenceBean对象
org.apache.dubbo.config.spring.beans.factory.annotation.AnnotatedInterfaceConfigBeanBuilder#build
@Override
protected ReferenceBean doBuild() {
return new ReferenceBean<Object>();
}
可以看到我们手动new了一个,并且继承了ReferenceConfig,实现了FactoryBean
都是从@Reference注解中拿属性并设置到方法上
4.注册ReferenceBean到spring容器中
如果容器包含@Service的beanName,那么就把ServiceBean的ref 起个别名 就是我们ReferenceBean的名字,这样注入的时候就注入本地bean了
注册ReferenceBean到spring容器中
此处这么做就⽀持了可以通过@Autowired注解也可以使⽤服务了,ReferenceBean是 ⼀个FactoryBean
5.就是个缓存,过
6.获取要注入的对象
如果本地不存在ServiceBean,那么就调用get方法
这部分逻辑服务引入文章讲解
如果本地存在ServiceBean