美文网首页
spring下dubbo启动时究竟会如何决定Protocol和R

spring下dubbo启动时究竟会如何决定Protocol和R

作者: dracula337435 | 来源:发表于2019-06-30 17:36 被阅读0次

    复杂系统中可能出现想给不同dubbo服务指定不同ProtocolRegistry的需求,显式逐个指定一定有效。
    但是,显式逐个指定的做法过于繁琐。如果利用默认机制,用较少显式配置就实现目标就再好不过了。
    此外,举个失误案例,想当然认为,服务会使用被定义在同一个xml中的ProtocolRegistry,但实际情况不是这样。
    本文尝试从源码一级分析springdubbo启动时如何选择ProtocolRegistry

    先给结论

    会用整个spring上下文中的所有ProtocolRegistry
    不论是xml还是@Configuration,无论是否在一个中
    如有特殊配置的话,可能会少用些

    代码一级的解释

    dubbo的xml配置下,<dubbo:>命名空间的元素方式会被DubboNamespaceHandler处理。
    具体来说,<dubbo:service><dubbo:reference>会分别被上述Handler处理成ServiceBeanReferenceBean并注册进上下文中。
    ServiceBeanpublic void afterPropertiesSet() throws Exception方法片段如下:

    Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false);
    if (registryConfigMap != null && registryConfigMap.size() > 0) {
        List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
        for (RegistryConfig config : registryConfigMap.values()) {
            if (config.isDefault() == null || config.isDefault().booleanValue()) {
                registryConfigs.add(config);
            }
        }
        if (registryConfigs != null && !registryConfigs.isEmpty()) {
            super.setRegistries(registryConfigs);
        }
    }
    

    这段代码主要做的事如下

    1. ApplicationContext中找出所有RegistryConfig类型的bean
    2. 在这些bean中,找到未设置default属性(为null)或default属性为true的,放入一个list
    3. 若上述listnull非空,则将其作为registries

    至此可知选择Registry的两个标准

    1. ApplicationContext中找出所有RegistryConfig
    2. 未设置default属性(为null)或default属性为true

    在这段代码外,还有一个if判断,如下:

    if ((getRegistries() == null || getRegistries().isEmpty())
            && (getProvider() == null || getProvider().getRegistries() == null || getProvider().getRegistries().isEmpty())
            && (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().isEmpty())) {
        // 省略,前一段代码
    }
    

    这段判断的顺序主要为,依次判断ServiceBean自己,ProviderApplication中是否没有registries配置
    再回头看ServiceBean中整个afterPropertiesSet()方法

    public void afterPropertiesSet() throws Exception {
        // 略对Provider、Application和Module的配置
        if ((getRegistries() == null || getRegistries().isEmpty())
                && (getProvider() == null || getProvider().getRegistries() == null || getProvider().getRegistries().isEmpty())
                && (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().isEmpty())) {
            Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false);
            if (registryConfigMap != null && registryConfigMap.size() > 0) {
                List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
                for (RegistryConfig config : registryConfigMap.values()) {
                    if (config.isDefault() == null || config.isDefault().booleanValue()) {
                        registryConfigs.add(config);
                    }
                }
                if (registryConfigs != null && !registryConfigs.isEmpty()) {
                    super.setRegistries(registryConfigs);
                }
            }
        }
        // 略对Monitor的配置
        if ((getProtocols() == null || getProtocols().isEmpty())
                && (getProvider() == null || getProvider().getProtocols() == null || getProvider().getProtocols().isEmpty())) {
            Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);
            if (protocolConfigMap != null && protocolConfigMap.size() > 0) {
                List<ProtocolConfig> protocolConfigs = new ArrayList<ProtocolConfig>();
                for (ProtocolConfig config : protocolConfigMap.values()) {
                    if (config.isDefault() == null || config.isDefault().booleanValue()) {
                        protocolConfigs.add(config);
                    }
                }
                if (protocolConfigs != null && !protocolConfigs.isEmpty()) {
                    super.setProtocols(protocolConfigs);
                }
            }
        }
        // 略对Path的配置,export
    }
    

    其中可见,选择RegistryProtocol的逻辑大同小异

    相关文章

      网友评论

          本文标题:spring下dubbo启动时究竟会如何决定Protocol和R

          本文链接:https://www.haomeiwen.com/subject/legpbqtx.html