EnableDubbo注解解析(一)------ EnableDubboConfig注解

@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;

}

EnableDubboConfig注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Import(DubboConfigConfigurationRegistrar.class) //看到导入进来的这个类
public @interface EnableDubboConfig {

    //默认支持多个dubbo配置bean
    boolean multiple() default true;

}

DubboConfigConfigurationRegistrar

public class DubboConfigConfigurationRegistrar implements ImportBeanDefinitionRegistrar {
	
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        AnnotationAttributes attributes = AnnotationAttributes.fromMap(
                importingClassMetadata.getAnnotationAttributes(EnableDubboConfig.class.getName()));
		//获取到multiple属性的值
        boolean multiple = attributes.getBoolean("multiple");
		
        //将该bean注册到spring容器中
        registerBeans(registry, DubboConfigConfiguration.Single.class);
		
		//支持多个dubbo配置bean 
        if (multiple) { // Since 2.6.6 https://github.com/apache/incubator-dubbo/issues/3193
            registerBeans(registry, DubboConfigConfiguration.Multiple.class);
        }
    }
}

Single 和 Multiple,用来引入EnableDubboConfigBindings注解。

public class DubboConfigConfiguration {
	//一般的单配置bean
    @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)
    })
    public static class Single {

    }
	//支持多配置bean
    @EnableDubboConfigBindings({
            @EnableDubboConfigBinding(prefix = "dubbo.applications", type = ApplicationConfig.class, multiple = true),
            @EnableDubboConfigBinding(prefix = "dubbo.modules", type = ModuleConfig.class, multiple = true),
            @EnableDubboConfigBinding(prefix = "dubbo.registries", type = RegistryConfig.class, multiple = true),
            @EnableDubboConfigBinding(prefix = "dubbo.protocols", type = ProtocolConfig.class, multiple = true),
            @EnableDubboConfigBinding(prefix = "dubbo.monitors", type = MonitorConfig.class, multiple = true),
            @EnableDubboConfigBinding(prefix = "dubbo.providers", type = ProviderConfig.class, multiple = true),
            @EnableDubboConfigBinding(prefix = "dubbo.consumers", type = ConsumerConfig.class, multiple = true)
    })
    public static class Multiple {

   }
}

EnableDubboConfigBindings

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(DubboConfigBindingsRegistrar.class) //看到这个类
public @interface EnableDubboConfigBindings {
    EnableDubboConfigBinding[] value();
}

DubboConfigBindingsRegistrar

public class DubboConfigBindingsRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware {

    private ConfigurableEnvironment environment;

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

        AnnotationAttributes attributes = AnnotationAttributes.fromMap(
                importingClassMetadata.getAnnotationAttributes(EnableDubboConfigBindings.class.getName()));
		//获得所有EnableDubboConfigBinding注解
        AnnotationAttributes[] annotationAttributes = attributes.getAnnotationArray("value");
		
		//设置environment对象到DubboConfigBindingRegistrar中
        DubboConfigBindingRegistrar registrar = new DubboConfigBindingRegistrar();
        registrar.setEnvironment(environment);
		
		//解析所有的EnableDubboConfigBinding注解
        for (AnnotationAttributes element : annotationAttributes) {
			//从environment中取得配置属性,实例化配置类,然后注册为bean
            registrar.registerBeanDefinitions(element, registry);

        }
    }

    @Override
    public void setEnvironment(Environment environment) {

        Assert.isInstanceOf(ConfigurableEnvironment.class, environment);

        this.environment = (ConfigurableEnvironment) environment;
    }
}

DubboConfigBindingRegistrar

public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware {

    private final Log log = LogFactory.getLog(getClass());

    private ConfigurableEnvironment environment;
	
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		
		//获取EnableDubboConfigBinding注解中的属性值
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(
                importingClassMetadata.getAnnotationAttributes(EnableDubboConfigBinding.class.getName()));
		//接着看
        registerBeanDefinitions(attributes, registry);

    }
	
    protected void registerBeanDefinitions(AnnotationAttributes attributes, BeanDefinitionRegistry registry) {
		
		//获取配置属性前缀
        String prefix = environment.resolvePlaceholders(attributes.getString("prefix"));
		//获取需要实例化的配置类
        Class<? extends AbstractConfig> configClass = attributes.getClass("type");
		//是否需要有多个配置bean
        boolean multiple = attributes.getBoolean("multiple");
		
        registerDubboConfigBeans(prefix, configClass, multiple, registry);

    }

    private void registerDubboConfigBeans(String prefix,
                                          Class<? extends AbstractConfig> configClass,
                                          boolean multiple,
                                          BeanDefinitionRegistry registry) {
		//调用PropertySourcesUtils的静态方法getSubProperties(限于篇幅这里就不贴出来了,就是从environment中拿到值)
		//拿到 该前缀的 后续属性 和  值的映射关系  比如 (prefix为dubbo.application,然后配置了dubbo.application.name=dubbo_provider,这里就拿到了name 和 dubbo_provider)
        Map<String, Object> properties = getSubProperties(environment.getPropertySources(), prefix);
		
		//没有该前缀的配置属性,则直接返回,不在这里去注册该配置bean
        if (CollectionUtils.isEmpty(properties)) {
            if (log.isDebugEnabled()) {
                log.debug("There is no property for binding to dubbo config class [" + configClass.getName()
                        + "] within prefix [" + prefix + "]");
            }
            return;
        }
		//如果multiple 为true , 则多个配置bean , 调用resolveMultipleBeanNames解析properties获取beanName集合
		//false 则调用resolveSingleBeanName获取beanName
        Set<String> beanNames = multiple ? resolveMultipleBeanNames(properties) :
                Collections.singleton(resolveSingleBeanName(properties, configClass, registry));
		//循环所有的beanName
        for (String beanName : beanNames) {
			//使用beanName注册dubbo配置bean
            registerDubboConfigBean(beanName, configClass, registry);
			//由于配置bean的属性还没有填充,这里为每一个配置bean注册一个DubboConfigBindingBeanPostProcessor来进行属性填充
            registerDubboConfigBindingBeanPostProcessor(prefix, beanName, multiple, registry);

        }

        registerDubboConfigBeanCustomizers(registry);

    }

    private void registerDubboConfigBean(String beanName, Class<? extends AbstractConfig> configClass,
                                         BeanDefinitionRegistry registry) {
		
		//实例化BeanDefinition 
        BeanDefinitionBuilder builder = rootBeanDefinition(configClass);
        AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
		//注册到spring容器中
        registry.registerBeanDefinition(beanName, beanDefinition);

        if (log.isInfoEnabled()) {
            log.info("The dubbo config bean definition [name : " + beanName + ", class : " + configClass.getName() +
                    "] has been registered.");
        }

    }

    private void registerDubboConfigBindingBeanPostProcessor(String prefix, String beanName, boolean multiple,
                                                             BeanDefinitionRegistry registry) {
		
        Class<?> processorClass = DubboConfigBindingBeanPostProcessor.class;
        BeanDefinitionBuilder builder = rootBeanDefinition(processorClass);
		//如果支持多配置bean , 需要拿到带上名称的前缀,来匹配不同名称的相同的配置类  比如(dubbo.applications.application1.name,dubbo.applications.application2.name)
		//单配置bean 则直接获取前缀 比如(dubbo.application)
        String actualPrefix = multiple ? normalizePrefix(prefix) + beanName : prefix;
		//DubboConfigBindingBeanPostProcessor的构造函数,需要 配置属性的前缀 和 beanName 来匹配对应的bean和对应的配置属性 进行 配置bean的属性填充
        builder.addConstructorArgValue(actualPrefix).addConstructorArgValue(beanName);
		//实例化DubboConfigBindingBeanPostProcessor类为BeanDefinition 
        AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();

        beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		//注册到spring容器中
        registerWithGeneratedName(beanDefinition, registry);

        if (log.isInfoEnabled()) {
            log.info("The BeanPostProcessor bean definition [" + processorClass.getName()
                    + "] for dubbo config bean [name : " + beanName + "] has been registered.");
        }

    }
	
	//注册了一个NamePropertyDefaultValueDubboConfigBeanCustomizer(实现了DubboConfigBeanCustomizer接口,由DubboConfigBindingBeanPostProcessor调用)到spring容器中(限于篇幅这里就不贴出来了,比较简单)
	//如果配置bean中有name属性,有setName的方法给name属性赋值,然后配置属性中配置name属性值,则反射调用setName方法给配置类的name属性赋值
    private void registerDubboConfigBeanCustomizers(BeanDefinitionRegistry registry) {
        registerInfrastructureBean(registry, "namePropertyDefaultValueDubboConfigBeanCustomizer",
                NamePropertyDefaultValueDubboConfigBeanCustomizer.class);
    }

    @Override
    public void setEnvironment(Environment environment) {

        Assert.isInstanceOf(ConfigurableEnvironment.class, environment);

        this.environment = (ConfigurableEnvironment) environment;

    }
	
    private Set<String> resolveMultipleBeanNames(Map<String, Object> properties) {
		
        Set<String> beanNames = new LinkedHashSet<String>();
		//此时的propertyName 的前缀已经被截取掉了(dubbo.applications.application1.name 此时的propertyName为application1.name。直接用截取出application1作为beanName)
        for (String propertyName : properties.keySet()) {

            int index = propertyName.indexOf(".");

            if (index > 0) {

                String beanName = propertyName.substring(0, index);

                beanNames.add(beanName);
            }

        }

        return beanNames;

    }

    private String resolveSingleBeanName(Map<String, Object> properties, Class<? extends AbstractConfig> configClass,
                                         BeanDefinitionRegistry registry) {
		//使用id属性值做为beanName
        String beanName = (String) properties.get("id");
		//如果没有配置id属性
        if (!StringUtils.hasText(beanName)) {
            BeanDefinitionBuilder builder = rootBeanDefinition(configClass);
            //调用BeanDefinitionReaderUtils的静态方法generateBeanName来自动生成一个beanName
            beanName = BeanDefinitionReaderUtils.generateBeanName(builder.getRawBeanDefinition(), registry);
        }

        return beanName;

    }

}

DubboConfigBindingBeanPostProcessor实现了BeanPostProcessor和InitializingBean接口

public class DubboConfigBindingBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware, InitializingBean {

    private final Log log = LogFactory.getLog(getClass());
    
    private final String prefix;
    
    private final String beanName;

    private DubboConfigBinder dubboConfigBinder;

    private ApplicationContext applicationContext;

    private List<DubboConfigBeanCustomizer> configBeanCustomizers = Collections.emptyList();

    public DubboConfigBindingBeanPostProcessor(String prefix, String beanName) {
        Assert.notNull(prefix, "The prefix of Configuration Properties must not be null");
        Assert.notNull(beanName, "The name of bean must not be null");
        this.prefix = prefix;
        this.beanName = beanName;
    }
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		//每个DubboConfigBindingBeanPostProcessor只负责对应的配置bean的属性填充
		//配置bean的顶级父类AbstractConfig
        if (beanName.equals(this.beanName) && bean instanceof AbstractConfig) {
			
            AbstractConfig dubboConfig = (AbstractConfig) bean;
			//完成配置属性的赋值
            bind(prefix, dubboConfig);
			//调用实现了DubboConfigBeanCustomizer接口的bean的customize方法
            customize(beanName, dubboConfig);
        }
        return bean;
    }

    private void bind(String prefix, AbstractConfig dubboConfig) {
		//调用DubboConfigBinder调用的bind方法,完成配置填充
        dubboConfigBinder.bind(prefix, dubboConfig);

        if (log.isInfoEnabled()) {
            log.info("The properties of bean [name : " + beanName + "] have been binding by prefix of " +
                    "configuration properties : " + prefix);
        }
    }

    private void customize(String beanName, AbstractConfig dubboConfig) {
		//循环所有的DubboConfigBeanCustomizer , 完成customize调用
        for (DubboConfigBeanCustomizer customizer : configBeanCustomizers) {
            customizer.customize(beanName, dubboConfig);
        }

    }

    public DubboConfigBinder getDubboConfigBinder() {
        return dubboConfigBinder;
    }

    public void setDubboConfigBinder(DubboConfigBinder dubboConfigBinder) {
        this.dubboConfigBinder = dubboConfigBinder;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
	//先看到afterPropertiesSet,完成初始化工作
    @Override
    public void afterPropertiesSet() throws Exception {

        initDubboConfigBinder();

        initConfigBeanCustomizers();

    }
	
    private void initDubboConfigBinder() {
		//获取DubboConfigBinder赋值给dubboConfigBinder变量,来进行配置bean的属性赋值
        if (dubboConfigBinder == null) {
            try {
            	//默认找不到,会进入catch
            	//默认的DefaultDubboConfigBinder并没有加入到spring容器中
                dubboConfigBinder = applicationContext.getBean(DubboConfigBinder.class);
            } catch (BeansException ignored) {
                if (log.isDebugEnabled()) {
                    log.debug("DubboConfigBinder Bean can't be found in ApplicationContext.");
                }
                // Use Default implementation
                //创建DefaultDubboConfigBinder赋值给dubboConfigBinder 
                dubboConfigBinder = createDubboConfigBinder(applicationContext.getEnvironment());
            }
        }

    }
	
    private void initConfigBeanCustomizers() {
		//从spring容器中获取实现了DubboConfigBeanCustomizer接口的所有bean,默认有一个NamePropertyDefaultValueDubboConfigBeanCustomizer,由DubboConfigBindingRegistrar注册进来的
        Collection<DubboConfigBeanCustomizer> configBeanCustomizers =
                beansOfTypeIncludingAncestors(applicationContext, DubboConfigBeanCustomizer.class).values();
		
        this.configBeanCustomizers = new ArrayList<DubboConfigBeanCustomizer>(configBeanCustomizers);
		//排序,DubboConfigBeanCustomizer接口继承了Ordered接口,可以满足按顺序调用的需求
        AnnotationAwareOrderComparator.sort(this.configBeanCustomizers);
    }
	//创建DefaultDubboConfigBinder 返回 ,持有了environment对象,可以获取到配置信息
    protected DubboConfigBinder createDubboConfigBinder(Environment environment) {
        DefaultDubboConfigBinder defaultDubboConfigBinder = new DefaultDubboConfigBinder();
        defaultDubboConfigBinder.setEnvironment(environment);
		//忽略不存在的字段
        defaultDubboConfigBinder.setIgnoreUnknownFields(true);
        //忽略无法访问的字段
        defaultDubboConfigBinder.setIgnoreInvalidFields(true);

        return defaultDubboConfigBinder;
    }

}

DefaultDubboConfigBinder

public class DefaultDubboConfigBinder extends AbstractDubboConfigBinder {

    @Override
    public <C extends AbstractConfig> void bind(String prefix, C dubboConfig) {
    	//实例化DataBinder , 给配置类填充属性
        DataBinder dataBinder = new DataBinder(dubboConfig);
        dataBinder.setIgnoreInvalidFields(isIgnoreInvalidFields());
        dataBinder.setIgnoreUnknownFields(isIgnoreUnknownFields());
        //首先调用父类的getPropertySources()获取所有的配置属性
        //然后调用PropertySourcesUtils的静态方法getSubProperties 拿到 该前缀的 后续属性 和  值的映射关系  
        Map<String, Object> properties = getSubProperties(getPropertySources(), prefix);
        //实例化MutablePropertyValues对象
        MutablePropertyValues propertyValues = new MutablePropertyValues(properties);
        // 完成配置类的属性绑定
        dataBinder.bind(propertyValues);
    }

}

AbstractDubboConfigBinder

public abstract class AbstractDubboConfigBinder implements DubboConfigBinder {

    private Iterable<PropertySource<?>> propertySources;

    private boolean ignoreUnknownFields = true;

    private boolean ignoreInvalidFields = false;

    protected Iterable<PropertySource<?>> getPropertySources() {
        return propertySources;
    }

    public boolean isIgnoreUnknownFields() {
        return ignoreUnknownFields;
    }

    @Override
    public void setIgnoreUnknownFields(boolean ignoreUnknownFields) {
        this.ignoreUnknownFields = ignoreUnknownFields;
    }

    public boolean isIgnoreInvalidFields() {
        return ignoreInvalidFields;
    }

    @Override
    public void setIgnoreInvalidFields(boolean ignoreInvalidFields) {
        this.ignoreInvalidFields = ignoreInvalidFields;
    }
	//获取environment的所有配置属性赋值给propertySources变量
    @Override
    public final void setEnvironment(Environment environment) {

        if (environment instanceof ConfigurableEnvironment) {
            this.propertySources = ((ConfigurableEnvironment) environment).getPropertySources();
        }

    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值