上面使用的dubbo版本是2.6.2版本的,然后我分析源码时候使用的是gitHub上最新下载的版本2.7.1的版本。在自习对比之后发现了部分差异,但是大致的逻辑并没有太大的影响。接下来就进入分析。
在前面搭建环境的时候我们只是在启动类上面贴了一个EnableDubbo的注解。从这里开始着手。
1.EnableDubbo标签
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@EnableDubboConfig
@DubboComponentScan
public @interface EnableDubbo {
//用于指定扫描那些包包含@Service注解(声明后面提到Service注解都是Dubbo的Service注解)
@AliasFor(annotation = DubboComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
//用于指定扫描那些类包含@service注解
@AliasFor(annotation = DubboComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
//表示是否绑定到多个bean。
//举例:作用是按照不同的配置文件格式进行选择。比如:dubbo.registry跟dubbo.registries之间的区别
@AliasFor(annotation = EnableDubboConfig.class, attribute = "multiple")
boolean multipleConfig() default false;
}
可以发现EnableDubbo注解其实是EnableDubboConfig跟DubboComponentScan标签的合并。先进入EnableDubboConfig注解
2.EnableDubboConfig分析
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Import(DubboConfigConfigurationRegistrar.class)
public @interface EnableDubboConfig {
boolean multiple() default false;
}
可以看到这里使用Import标签指向了DubboConfigConfigurationRegistrar类(这里称呼为R类)。
2.1版本上的细微的区别
需要注意的是,我使用的2.6.2版本中,指向的是DubboConfigConfigurationSelector类(这里称呼为S类)。其中R类实现的是ImportBeanDefinitionRegistrar接口类,S类实现的是ImportSelector类。这两个类都是Spring中的类。虽然R类跟S类实现的类不同,但是这两个类的父接口的作用是相同的。
- ImportSelector接口中只有一个方法selectImports作用是指定需要注册为bean的Class名称。当在@Configuration标注的Class上使用@Import引入了一个ImportSelector实现类后,会把实现类中返回的Class名称都定义为bean。
- ImportBeanDefinitionRegistrar的用法和作用跟ImportSelector类似。唯一的不同点是ImportBeanDefinitionRegistrar的接口方法registerBeanDefinitions,返回类型是void,且多了一个BeanDefinitionRegistry类型的参数,它允许我们直接通过BeanDefinitionRegistry对象注册bean。在实现类中可以使用ClassPathBeanDefinitionScanner进行扫描并自动注册,它是ClassPathScanningCandidateComponentProvider的子类,所以还是可以添加相同的TypeFilter,然后通过scanner.scan(basePackages)扫描指定的basePackage下满足条件的Class并注册它们为bean。
2.2DubboConfigConfigurationRegistrar类
这里分析最新版本的,就是实现了ImportBeanDefinitionRegistrar接口的。
public class DubboConfigConfigurationRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//从importingClassMetadata对象(这个对象中包含启动类上的标签和其他信息)中获取EnableDubboConfig标签中的属性,并保存在map中然后封装到AnnotationAttributes中
AnnotationAttributes attributes = AnnotationAttributes.fromMap(
importingClassMetadata.getAnnotationAttributes(EnableDubboConfig.class.getName()));
//获取EnableDubboConfig标签中的multiple属性
boolean multiple = attributes.getBoolean("multiple");
//根据是否绑定到多个Bean分情况处理,并注册Bean。
if (multiple) {
registerBeans(registry, DubboConfigConfiguration.Multiple.class);
} else {
re