Dubbo源码学习一

2020-07-16 21:37:25 浏览数 (1)

首先,我们知道dubbo在以前都是基于zookeeper作为配置中心的,同时是建立在spring基础之上的。因此,就需要思考一些问题:

首先dubbo是怎样和spring集成的,也即dubbo集成在spring上需要具备什么条件?接着dubbo作为一个服务治理的微服务框架,那它的生产者和消费者与注册中心怎样进行交互的。

dubbo是基于spring的基础之上进行开发的RPC框架。需要和spring整合,必然就需要按照Spring解析默认标签和自定义标签的方式进行。而在Spring中,我们知道在Spring中是在ParseBeanDefintions(Element root,BeanDefintonParserDelegate delegate)方法对默认标签parseDefaultElement(ele,delegate)和自定义标签delegate.parseCustomElement(ele)进行了解析。可以看到对自定义标签的解析:

1.首先拿到命名空间namespaceuri

2.根据命名空间找到对应的NamespaceHandler

3.调用自定义的NamespaceHandler进行解析

而自定义标签的步骤:

1.首先创建一个需要进行扩展的组件

2.定义一个xsd文件描述组件内容

3.创建一个文件,实现BeanDefintionParser接口,用来解析xsd文件中的定义和组件定义

4.创建一个handler文件,扩展自NamespaceHandlerSupport,目的是将组件注册到spring容器

5..编写Spring.handlers和spring.schemas文件

也即我们可以通过这个找到dubbo的入口--dubbo-config-spring。

接着我们就可以找到解析schemas文件的BeanDefintionParser和NamespceHandlerSupport了。因此我们首先关注NamespaceHandkerSupport。

代码语言:javascript复制
//dubbo入口
public class DubboNamespaceHandler extends NamespaceHandlerSupport implements ConfigurableSourceBeanMetadataElement {

    static {
        Version.checkDuplicate(DubboNamespaceHandler.class);
    }

    //找到入口,解析Dubbo的相关标签的
    @Override
    public void init() {
        //将解析好的元素的key-value信息放入到BeanDefintionMap中
        //registerBeanDefinitionParser(String elementName, BeanDefinitionParser parser);
        //this.parsers.put(elementName, parser);
        // DubboBeanDefinitionParser(Class<?> beanClass, boolean required),也是key-value的map形式
        registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
        registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
        registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
        registerBeanDefinitionParser("config-center", new DubboBeanDefinitionParser(ConfigCenterBean.class, true));
        registerBeanDefinitionParser("metadata-report", new DubboBeanDefinitionParser(MetadataReportConfig.class, true));
        registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
        registerBeanDefinitionParser("metrics", new DubboBeanDefinitionParser(MetricsConfig.class, true));
        registerBeanDefinitionParser("ssl", new DubboBeanDefinitionParser(SslConfig.class, true));
        registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
        registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
        registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
        registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
        registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
        registerBeanDefinitionParser("annotation", new AnnotationBeanDefinitionParser());
    }

    /**
     * 复写NamespaceHandlerSupport的parse方法,为注解配置服务
     * @since 2.7.5
     */
    @Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        BeanDefinitionRegistry registry = parserContext.getRegistry();
        //注册注解配置处理器
        registerAnnotationConfigProcessors(registry);
        //注册上下文监听器
        registerApplicationListeners(registry);
        //进行bena的解析
        BeanDefinition beanDefinition = super.parse(element, parserContext);
        //设置资源
        setSource(beanDefinition);
        return beanDefinition;
    }

    /**
     * 将{@link ApplicationListener ApplicationListeners}注册为Spring Bean
     * @since 2.7.5
     */
    private void registerApplicationListeners(BeanDefinitionRegistry registry) {
        //注册bean dubbo生命周期组件上下文监听
        registerBeans(registry, DubboLifecycleComponentApplicationListener.class);
        //注册bean dubbo服务器上下文监听
        registerBeans(registry, DubboBootstrapApplicationListener.class);
    }

    /**
     *  注册注解配置处理器
     * @since 2.7.5
     */
    private void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
        AnnotationConfigUtils.registerAnnotationConfigProcessors(registry);
    }
}

从入口,我们可以看到相关配置信息:

ApplicationConfig、ModuleConfig、RegistryConfig、ConfigCenterBean、MetadataReportConfig、MonitorConifg、MetricsConfig、SslConfig、ProviderConfig、ConsumerConfig、ProtocolConfig、ServiceBean、ReferenceBean,还有一个注解解析:new AnnotationBeanDefinitionParser()。这里我们需要重点关注:

ServiceBean、ReferenceBean、ConfigCenterBean、new AnnotationBeanDefintionParser()

而对于相关config的配置,我们来看一个ApplicationConfig,关注两个方法,其余带config的信息都是一些实体类的信息:

代码语言:javascript复制
 //进行刷新操作,继承父类的refresh
@Override
public void refresh() {
    super.refresh();
    appendEnvironmentProperties();
}

//调用父类AbstractConfig#refresh方法
 //进行刷新操作
public void refresh() {
    //拿到环境变量信息
    Environment env = ApplicationModel.getEnvironment();
    try {
        CompositeConfiguration compositeConfiguration = env.getPrefixedConfiguration(this);
        //循环方法,将新的value设置到方法中
        Method[] methods = getClass().getMethods();
        for (Method method : methods) {
            //setter方法
            if (MethodUtils.isSetter(method)) {
                try {
                    String value = StringUtils.trim(compositeConfiguration.getString(extractPropertyName(getClass(), method)));
                     //调用isTypeMatch()方法以避免重复和不正确的更新,例如,
                    //在ReferenceConfig中我们有两个“ setGeneric”方法。
                    if (StringUtils.isNotEmpty(value) && ClassUtils.isTypeMatch(method.getParameterTypes()[0], value)) {
                        //在具有指定参数的指定对象上,调用此方法对象表示的基础方法。
                        //各个参数将自动展开以匹配原始形式参数,并且必要时对原始
                        //参数和引用参数都进行方法调用转换。
                        method.invoke(this, ClassUtils.convertPrimitive(method.getParameterTypes()[0], value));
                    }
                } catch (NoSuchMethodException e) {
                    logger.info("Failed to override the property "   method.getName()   " in "  
                                this.getClass().getSimpleName()  
                                ", please make sure every property has getter/setter method provided.");
                }
                //参数sette
            } else if (isParametersSetter(method)) {
                String value = StringUtils.trim(compositeConfiguration.getString(extractPropertyName(getClass(), method)));
                if (StringUtils.isNotEmpty(value)) {
                    Map<String, String> map = invokeGetParameters(getClass(), this);
                    map = map == null ? new HashMap<>() : map;
                    map.putAll(convert(StringUtils.parseParameters(value), ""));
                    invokeSetParameters(getClass(), this, map);
                }
            }
        }
    } catch (Exception e) {
        //复写失败
        logger.error("Failed to override ", e);
    }
}

//添加环境变量配置信息
private void appendEnvironmentProperties() {
    if (parameters == null) {
        parameters = new HashMap<>();
    }
    //通过扩展加载器进行获取适配器
    Set<InfraAdapter> adapters = ExtensionLoader.getExtensionLoader(InfraAdapter.class).getSupportedExtensionInstances();
    if (CollectionUtils.isNotEmpty(adapters)) {
        Map<String, String> inputParameters = new HashMap<>();
        //包含信息:应用名称和hos以及扩展参数信息
        inputParameters.put(APPLICATION_KEY, getName());
        inputParameters.put(HOST_KEY, getHostname());
        for (InfraAdapter adapter : adapters) {
            //同时将SPI的扩展参数信息信息加入
            Map<String, String> extraParameters = adapter.getExtraAttributes(inputParameters);
            if (CollectionUtils.isNotEmptyMap(extraParameters)) {
                parameters.putAll(extraParameters);
            }
        }
    }
}

明天,我们关注ServiceBean、ReferenceBean、ConfigCenterBean、new AnnotationBeanDefintionParser()这四个!

0 人点赞