@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@EnableDubboConfig //读取配置文件 创建dubbo配置bean
@DubboComponentScan //扫描 @Service(不是spring的Sevice注解) @Reference 生成 bean
public @interface EnableDubbo {
@AliasFor(annotation = DubboComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
@AliasFor(annotation = DubboComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
@AliasFor(annotation = EnableDubboConfig.class, attribute = "multiple")
boolean multipleConfig() default true;
}
DubboComponentScan注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(DubboComponentScanRegistrar.class) //看到导入进来的DubboComponentScanRegistrar
public @interface DubboComponentScan {
String[] value() default {};
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
}
DubboComponentScanRegistrar
public class DubboComponentScanRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//获取要扫描的包路径
Set<String> packagesToScan = getPackagesToScan(importingClassMetadata);
//注册ServiceAnnotationBeanPostProcessor来扫描含有Service注解的类 注冊到spring容器中
registerServiceAnnotationBeanPostProcessor(packagesToScan, registry);
//注册ReferenceAnnotationBeanPostProcessor来扫描含有Reference注解字段和方法,实现依赖注入
registerReferenceAnnotationBeanPostProcessor(registry);
}
private void registerServiceAnnotationBeanPostProcessor(Set<String> packagesToScan, BeanDefinitionRegistry registry) {
BeanDefinitionBuilder builder = rootBeanDefinition(ServiceAnnotationBeanPostProcessor.class);
//将扫描的包路径通过构造函数传给ServiceAnnotationBeanPostProcessor
builder.addConstructorArgValue(packagesToScan);
builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, registry);
}
private void registerReferenceAnnotationBeanPostProcessor(BeanDefinitionRegistry registry) {
// Register @Reference Annotation Bean Processor
BeanRegistrar.registerInfrastructureBean(registry,
ReferenceAnnotationBeanPostProcessor.BEAN_NAME, ReferenceAnnotationBeanPostProcessor.class);
}
private Set<String> getPackagesToScan(AnnotationMetadata metadata) {
//获取DubboComponentScan注解的属性
AnnotationAttributes attributes = AnnotationAttributes.fromMap(
metadata.getAnnotationAttributes(DubboComponentScan.class.getName()));
//获取包路径
String[] basePackages = attributes.getStringArray("basePackages");
//获取类
Class<?>[] basePackageClasses = attributes.getClassArray("basePackageClasses");
//获取value属性值
String[] value = attributes.getStringArray("value");
//所有要扫描的包路径packagesToScan
//将各个属性对应的包名加入到packagesToScan 中
Set<String> packagesToScan = new LinkedHashSet<String>(Arrays.asList(value));
packagesToScan.addAll(Arrays.asList(basePackages));
for (Class<?> basePackageClass : basePackageClasses) {
//获取类所在的包路径
packagesToScan.add(ClassUtils.getPackageName(basePackageClass));
}
//如果属性都没配置,获取 使用该注解的类所在的包 作为扫描的包路径
if (packagesToScan.isEmpty()) {
return Collections.singleton(ClassUtils.getPackageName(metadata.getClassName()));
}
return packagesToScan;
}
}