首先跟大家做个说明,读Dubbo源码最好是先对Spring源码有一定的了解。如果大家需要,我也可以针对Spring框架做一系列源码的解读专栏。
不过不用担心,如果需要Spring的源码知识,文章中也会进行Spring源码铺垫介绍的。
如果内容中有没描述清楚的,或者大家在阅读源代码有疑问的,欢迎留言,看到就会及时回复。
为了更清楚的分析解释源码,源代码中部分不重要的内容可能会删减,保留重要内容方便大家理解。
本章主要内容:
- dubbo的启用。
- dubbo与Spring的整合。
dubbo的启用主要有两种方式
- 通过xml配置方式启用:
<dubbo:annotation package="com.*.*"/>
通过上面标签,实现注册ServiceAnnotationBeanPostProcessor和ReferenceAnnotationBeanPostProcessor。通过这两个BeanPostProcessor分别用来处理@Service和@Reference注解,实现服务的暴露和饮用
- 通过注解方式启用@EnableDubbo
@EnableDubbo(scanBasePackages = "cn.*")
@PropertySource("dubbo.properties")
@ComponentScan(basePackages = "cn.*")
public class AnnoBean {
}
EnableDubbo标签中包含两个注解
- @EnableDubboConfig:实现所有配置类的加载如ApplicationConfig,RegistryConfig,ProtocalConfig等
- @DubboComponentScan:作用和xml方式类似。注册ServiceAnnotationBeanPostProcessor和ReferenceAnnotationBeanPostProcessor,实现对@Service和@Reference注解的支持。
dubbo与Spring整合
接下来针对上面内容从源码角度分析一下,Dubbo与Spring框架的整合。
@EnableDubbo标签中,包含两个主要注解@EnableDubboConfig和@DubboComponentScan,接下来着重讲一下这两个注解。
@EnableDubboConfig
该注解主要根据dubbo.property文件创建dubbo配置类,如ApplicaitonConfig,RegistryConfig,ProtocolConfig,ProviderConfig等。
具体流程如下:
- DubboConfigConfigurationRegistrar类调用registerBeanDefinitions()注册DubboConfigConfiguration.Single.class到resitry中。
- DubboConfigConfiguration.Single.class类包含@EnableDubboConfigBindings注解,Spring会加载并解析该注解
- EnableDubboConfigBindings注解,import了DubboConfigBindingsRegistrar
- 遍历EnableDubboConfigBindings中的配置注解(Application,registry,protocol等)
- 【变成BeanDefinetion】registerDubboConfigBean将配置类(Application,registry,protocol等)转化为BeanDefinetion,注册到上下文。
- 【进行数据绑定】registerDubboConfigBindingBeanPostProcessor():为每个配置类BeanDefinition注册一个DubboConfigBindingBeanPostProcessor。
- 【进行数据绑定】通过DubboConfigBindingBeanPostProcessor,通过DataBinder在初始化bean中对进行配置Bean的数据绑定
Spring背景知识铺垫
ConfigurationClassPostProcessor。java loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());Spring背景知识说明:
- Spring容器管理的类,不论是通过xml加载的还是注解加载的,都需要先进行收集成Beandefinetion对象,然后再根据该对象进程Bean 的实例化。实例化完成之后交给Spring管理。
- @Import注解对应的类会在,Spring启动过程中由 ConfigurationClassPostProcessor扫描,收集@Import注解,并调用对应类中的registerBeanDefinitions()注册方法如DubboConfigConfigurationRegistrar中的
上述流程对应的源码
@EnableDubboConfig倒入了DubboConfigConfigurationRegistrar.class
@Import(DubboConfigConfigurationRegistrar.class)
public @interface EnableDubboConfig {
boolean multiple() default true;
}
DubboConfigConfiguration.Single.class:流程2
@EnableDubboConfigBindings({ @EnableDubboConfigBinding(prefix = "dubbo.application", type = ApplicationConfig.class), @EnableDubboConfigBinding(prefix = "dubbo.module", type = ModuleConfig.class), @EnableDubboConfigBinding(prefix = "dubbo.registry", type = RegistryConfig.class), @EnableDubboConfigBinding(prefix = "dubbo.protocol", type = ProtocolConfig.class), @EnableDubboConfigBinding(prefix = "dubbo.monitor", type = MonitorConfig.class), @EnableDubboConfigBinding(prefix = "dubbo.provider", type = ProviderConfig.class), @EnableDubboConfigBinding(prefix = "dubbo.consumer", type = ConsumerConfig.class) })
DubboConfigBindingsRegistrar. registerBeanDefinitions():流程3/4
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AnnotationAttributes attributes = AnnotationAttributes.fromMap(
importingClassMetadata.getAnnotationAttributes(EnableDubboConfigBindings.class.getName()));
AnnotationAttributes[] annotationAttributes = attributes.getAnnotationArray("value");
DubboConfigBindingRegistrar registrar = new DubboConfigBindingRegistrar();
registrar.setEnvironment(environment);
//遍历EnableDubboConfigBindings配置注解values集合(Application/Protocal/Registry等)
for (AnnotationAttributes element : annotationAttributes) {
//注册对应的BeanDefinition和数据绑定器
registrar.registerBeanDefinitions(element, registry);
}
}
DubboConfigBindingRegistrar.registerDubboConfigBeans():流程4
private void registerDubboConfigBeans(String prefix,
Class<? extends AbstractConfig> configClass,
boolean multiple,
BeanDefinitionRegistry registry) {
for (String beanName : beanNames) {
//这里是向spring注册各种配置Bean,比如ApplicationConfig
registerDubboConfigBean(beanName, configClass, registry);
//这里是注册负责每一种配置bean的BeanPostProcessor对象,在BeanPostProcessor进行配置Bean的数据绑定
registerDubboConfigBindingBeanPostProcessor(prefix, beanName, multiple, registry);
}
registerDubboConfigBeanCustomizers(registry);
}
@DubboComponentScan
由于篇幅问题,写到下一篇博客Dubbo源码解读-dubbo启动与Spring整合之@ DubboComponentScan-CSDN博客
知识总结,分享不易,全文手敲,欢迎大家点赞评论收藏。