Dubbo源码解析之服务提供者篇

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/heroqiang/article/details/79189798

阅读须知

  • dubbo版本:2.6.0
  • spring版本:4.3.8
  • 文章中使用/* */注释的方法会做深入分析

正文

dubbo的服务由ServiceBean暴露,我们先来看一下这个类的层次结构:
这里写图片描述
我们发现它实现了InitializingBean,InitializingBean接口的作用我想大家应该都很清楚了,实现了InitializingBean的bean,Spring会在填充bean的属性之后调用它的afterPropertiesSet方法,我们来看相关实现:
ServiceBean:

public void afterPropertiesSet() throws Exception {
    // 判断是否解析过provider配置,解析过则不再解析
    if (getProvider() == null) {
        // 获取所有ProviderConfig类型的bean
        Map<String, ProviderConfig> providerConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProviderConfig.class, false, false);
        if (providerConfigMap != null && providerConfigMap.size() > 0) {
            // 获取所有ProtocolConfig类型的bean
            Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);
            // 向后兼容,判断是否protocol为空并且provider不为空
            if ((protocolConfigMap == null || protocolConfigMap.size() == 0)
                        && providerConfigMap.size() > 1) {
                List<ProviderConfig> providerConfigs = new ArrayList<ProviderConfig>();
                for (ProviderConfig config : providerConfigMap.values()) {
                    if (config.isDefault() != null && config.isDefault().booleanValue()) {
                        // 添加默认的ProviderConfig
                        providerConfigs.add(config);
                    }
                }
                if (providerConfigs.size() > 0) {
                    // 将ProviderConfig转换为ProtocolConfig赋值给protocols成员属性
                    setProviders(providerConfigs);
                }
            } else {
                ProviderConfig providerConfig = null;
                for (ProviderConfig config : providerConfigMap.values()) {
                    if (config.isDefault() == null || config.isDefault().booleanValue()) {
                        // 默认的ProviderConfig只能有一个
                        if (providerConfig != null) {
                            throw new IllegalStateException("Duplicate provider configs: " + providerConfig + " and " + config);
                        }
                        providerConfig = config;
                    }
                }
                if (providerConfig != null) {
                    // 设置provider配置
                    setProvider(providerConfig);
                }
            }
        }
    }
    // 判断是否解析过application配置,解析过则不再解析
    if (getApplication() == null
        && (getProvider() == null || getProvider().getApplication() == null)) {
        // 获取所有ApplicationConfig类型的bean
        Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false);
        if (applicationConfigMap != null && applicationConfigMap.size() > 0) {
            ApplicationConfig applicationConfig = null;
            for (ApplicationConfig config : applicationConfigMap.values()) {
                if (config.isDefault() == null || config.isDefault().booleanValue()) {
                    // 默认的ApplicationConfig只能有一个
                    if (applicationConfig != null) {
                        throw new IllegalStateException("Duplicate application configs: " + applicationConfig + " and " + config);
                    }
                    applicationConfig = config;
                }
            }
            if (applicationConfig != null) {
                // 设置application配置
                setApplication(applicationConfig);
            }
        }
    }
    // 判断是否解析过module配置,解析过则不再解析
    if (getModule() == null
        && (getProvider() == null || getProvider().getModule() == null)) {
        // 获取所有ModuleConfig类型的bean
        Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class, false, false);
        if (moduleConfigMap != null && moduleConfigMap.size() > 0) {
            ModuleConfig moduleConfig = null;
            for (ModuleConfig config : moduleConfigMap.values()) {
                if (config.isDefault() == null || config.isDefault().booleanValue()) {
                    // 默认的ModuleConfig只能有一个
                    if (moduleConfig != null) {
                        throw new IllegalStateException("Duplicate module configs: " + moduleConfig + " and " + config);
                    }
                    moduleConfig = config;
                }
            }
            if (moduleConfig != null) {
                // 设置module配置
                setModule(moduleConfig);
            }
        }
    }
    // 判断是否解析过registry配置,解析过则不再解析
    if ((getRegistries() == null || getRegistries().size() == 0)
        && (getProvider() == null || getProvider().getRegistries() == null || getProvider().getRegistries().size() == 0)
        && (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().size() == 0)) {
        // 获取所有RegistryConfig类型的bean
        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()) {
                    // 添加RegistryConfig配置
                    registryConfigs.add(config);
                }
            }
            if (registryConfigs != null && registryConfigs.size() > 0) {
                // 设置registry配置
                super.setRegistries(registryConfigs);
            }
        }
    }
    // 判断是否解析过monitor配置,解析过则不再解析
    if (getMonitor() == null
        && (getProvider() == null || getProvider().getMonitor() == null)
        && (getApplication() == null || getApplication().getMonitor() == null)) {
        // 获取所有MonitorConfig类型的bean
        Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class, false, false);
        if (monitorConfigMap != null && monitorConfigMap.size() > 0) {
            MonitorConfig monitorConfig = null;
            for (MonitorConfig config : monitorConfigMap.values()) {
                if (config.isDefault() == null || config.isDefault().booleanValue()) {
                    // 默认的MonitorConfig只能有一个
                    if (monitorConfig != null) {
                        throw new IllegalStateException("Duplicate monitor configs: " + monitorConfig + " and " + config);
                    }
                    monitorConfig = config;
                }
            }
            if (monitorConfig != null) {
                // 设置monitor配置
                setMonitor(monitorConfig);
            }
        }
    }
    // 判断是否解析过protocol配置,解析过则不再解析
    if ((getProtocols() == null || getProtocols().size() == 0)
        && (getProvider() == null || getProvider().getProtocols() == null || getProvider().getProtocols().size() == 0)) {
        // 获取所有ProtocolConfig类型的bean
        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()) {
                    // 添加ProtocolConfig配置
                    protocolConfigs.add(config);
                }
            }
            if (protocolConfigs != null && protocolConfigs.size() > 0) {
                // 设置protocol配置
                super.setProtocols(protocolConfigs);
            }
        }
    }
    // 判断是否解析过path配置,解析过则不再解析
    if (getPath() == null || getPath().length() == 0) {
        // interface就是我们配置的interface
        if (beanName != null && beanName.length() > 0
            && getInterface() != null && getInterface().length() > 0
            && beanName.startsWith(getInterface())) {
            // 检查beanName的格式(长度、正则)并设置为path
            setPath(beanName);
        }
    }
    if (!isDelay()) {
        /* 没有设置延迟暴露则直接暴露 */
        export();
    }
}

ServiceConfig:

public synchronized void export() {
    if (provider != null) {
        // 确定是否暴露过
        if (export == null) {
            export = provider.getExport();
        }
        // 确定是否延迟暴露
        if (delay == null) {
            delay = provider.getDelay();
        }
    }
    // 暴露过不在暴露
    if (export != null && !export) {
        return;
    }
    // 延迟暴露
    if (delay != null && delay > 0) {
        delayExportExecutor.schedule(new Runnable() {
            public void run() {
                /* 作为ScheduledExecutorService的一个作业进行暴露 */
                doExport();
            }
        }, delay, TimeUnit.MILLISECONDS);
    } else {
        /* 暴露 */
        doExport();
    }
}

ServiceConfig:

protected synchronized void doExport() {
    if (unexported) {
        throw new IllegalStateException("Already unexported!");
    }
    if (exported) { // 暴露过直接返回
        return;
    }
    exported = true;
    if (interfaceName == null || interfaceName.length() == 0) {
        throw new IllegalStateException("<dubbo:service interface=\"\" /> interface not allow null!");
    }
    checkDefault(); /* 检查默认配置 */
    // 下面为一些配置成员属性的赋值
    if (provider != null) {
        if (application == null) {
            application = provider.getApplication();
        }
        if (module == null) {
            module = provider.getModule();
        }
        if (registries == null) {
            registries = provider.getRegistries();
        }
        if (monitor == null) {
            monitor = provider.getMonitor();
        }
        if (protocols == null) {
            protocols = provider.getProtocols();
        }
    }
    if (module != null) {
        if (registries == null) {
            registries = module.getRegistries();
        }
        if (monitor == null) {
            monitor = module.getMonitor();
        }
    }
    if (application != null) {
        if (registries == null) {
            registries = application.getRegistries();
        }
        if (monitor == null) {
            monitor = application.getMonitor();
        }
    }
    if (ref instanceof GenericService) {
        interfaceClass = GenericService.class;
        if (StringUtils.isEmpty(generic)) {
            generic = Boolean.TRUE.toString();
        }
    } else {
        try {
            interfaceClass = Class.forName(interfaceName, true, Thread.currentThread()
                .getContextClassLoader());
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
        // 检查接口和方法,接口不能为null并且必须是interface,方法必须属于接口
        checkInterfaceAndMethods(interfaceClass, methods);
        checkRef(); // 检查ref配置,不能为null,并且必须是配置的接口的实现类
        generic = Boolean.FALSE.toString();
    }
    if (local != null) {
        if ("true".equals(local)) {
            local = interfaceName + "Local";
        }
        Class<?> localClass;
        try {
            localClass = ClassHelper.forNameWithThreadContextClassLoader(local);
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
        if (!interfaceClass.isAssignableFrom(localClass)) {
            throw new IllegalStateException("The local implementation class " + localClass.getName() + " not implement interface " + interfaceName);
        }
    }
    if (stub != null) {
        if ("true".equals(stub)) {
            stub = interfaceName + "Stub";
        }
        Class<?> stubClass;
        try {
            stubClass = ClassHelper.forNameWithThreadContextClassLoader(stub);
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
        if (!interfaceClass.isAssignableFrom(stubClass)) {
            throw new IllegalStateException("The stub implementation class " + stubClass.getName() + " not implement interface " + interfaceName);
        }
    }
    checkApplication(); /* 检查application配置 */
    checkRegistry(); /* 检查registry配置 */
    checkProtocol(); /* 检查protocol配置 */
    appendProperties(this); /* 追加properties配置 */
    checkStubAndMock(interfaceClass); /* 检查stub、mock配置 */
    if (path == null || path.length() == 0) {
        path = interfaceName;
    }
    doExportUrls(); /* 暴露url */
    // 构造ProviderModel,将服务的方法封装成ProviderMethodModel保存到集合中,并将集合与方法名称做映射保存
    ProviderModel providerModel = new ProviderModel(getUniqueServiceName(), this, ref);
    // 获取服务唯一名称,注册到已提供服务列表中
    ApplicationModel.initProviderModel(getUniqueServiceName(), providerModel);
}

ServiceConfig:

private void checkDefault() {
    if (provider == null) {
        provider = new ProviderConfig();
    }
    /* 追加properties配置 */
    appendProperties(provider);
}

AbstractConfig:

protected static void appendProperties(AbstractConfig config) {
    if (config == null) {
        return;
    }
    // 获取标签名称(config名称除去Config或Bean后缀转成小写,例如ProviderConfig --> provider、ServiceBean --> service),拼接前缀,eg:ProviderConfig --> dubbo.provider.
    String prefix = "dubbo." + getTagName(config.getClass()) + ".";
    Method[] methods = config.getClass().getMethods();
    for (Method method : methods) {
        try {
            String name = method.getName();
            // 判断setter方法访问修饰符为public并且参数只有一个且是基本类型(包括包装类型、String和Object)
            if (name.length() > 3 && name.startsWith("set") && Modifier.isPublic(method.getModifiers())
                && method.getParameterTypes().length == 1 && isPrimitive(method.getParameterTypes()[0])) {
                // 将setter驼峰命名去掉set后转成.连接的命名,如setDumpDirectory --> dump.directory
                String property = StringUtils.camelToSplitName(name.substring(3, 4).toLowerCase() + name.substring(4), ".");
                String value = null;
                if (config.getId() != null && config.getId().length() > 0) {
                    // 如果id属性不为空,携带id拼接key尝试从系统属性中获取相关配置
                    String pn = prefix + config.getId() + "." + property;
                    value = System.getProperty(pn);
                    if (!StringUtils.isBlank(value)) {
                        logger.info("Use System Property " + pn + " to config dubbo");
                    }
                }
                if (value == null || value.length() == 0) {
                    // 如果id属性为空,不带id拼接key尝试从系统属性中获取相关配置
                    String pn = prefix + property;
                    value = System.getProperty(pn);
                    if (!StringUtils.isBlank(value)) {
                        logger.info("Use System Property " + pn + " to config dubbo");
                    }
                }
                if (value == null || value.length() == 0) {
                    Method getter;
                    try {
                        // 如果从系统属性中没有获取到配置,则尝试获取响应getter方法
                        getter = config.getClass().getMethod("get" + name.substring(3), new Class<?>[0]);
                    } catch (NoSuchMethodException e) {
                        try {
                            // boolean类型的属性的getter方法可能以is开头
                            getter = config.getClass().getMethod("is" + name.substring(3), new Class<?>[0]);
                        } catch (NoSuchMethodException e2) {
                            getter = null;
                        }
                    }
                    if (getter != null) {
                        // 判断调用getter方法的返回值是否为null
                        if (getter.invoke(config, new Object[0]) == null) {
                            if (config.getId() != null && config.getId().length() > 0) {
                                /* 如果id属性不为空,携带id拼接key尝试获取相关配置 */
                                value = ConfigUtils.getProperty(prefix + config.getId() + "." + property);
                            }
                            if (value == null || value.length() == 0) {
                                /* 如果value为空,不带id拼接key尝试获取相关配置 */
                                value = ConfigUtils.getProperty(prefix + property);
                            }
                            if (value == null || value.length() == 0) {
                                // 从预制的key映射中获取key
                                String legacyKey = legacyProperties.get(prefix + property);
                                if (legacyKey != null && legacyKey.length() > 0) {
                                    /* 尝试获取配置并转换(dubbo.service.max.retry.providers和dubbo.service.allow.no.provider两个配置需要转换) */
                                    value = convertLegacyValue(legacyKey, ConfigUtils.getProperty(legacyKey));
                                }
                            }
                        }
                    }
                }
                if (value != null && value.length() > 0) {
                    // 如果到这里value不为空,则调用setter方法为属性赋值
                    method.invoke(config, new Object[]{convertPrimitive(method.getParameterTypes()[0], value)});
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }
}

ConfigUtils:

public static String getProperty(String key) {
    /* 获取配置 */
    return getProperty(key, null);
}

ConfigUtils:

public static String getProperty(String key, String defaultValue) {
    String value = System.getProperty(key);
    if (value != null && value.length() > 0) {
        return value;
    }
    /* 获取properties配置 */
    Properties properties = getProperties();
    /* 将$和${}表达式替换为对应配置 */
    return replaceProperty(properties.getProperty(key, defaultValue), (Map) properties);
}

ConfigUtils:

public static String replaceProperty(String expression, Map<String, String> params) {
    // 表达式不含$忽略
    if (expression == null || expression.length() == 0 || expression.indexOf('$') < 0) {
        return expression;
    }
    // 正则为\$\s*\{?\s*([\._0-9a-zA-Z]+)\s*\}?
    Matcher matcher = VARIABLE_PATTERN.matcher(expression);
    StringBuffer sb = new StringBuffer();
    while (matcher.find()) {
        String key = matcher.group(1);
        // 首先尝试从系统属性中获取
        String value = System.getProperty(key);
        if (value == null && params != null) {
            // 没有再尝试从properties中获取
            value = params.get(key);
        }
        if (value == null) {
            value = "";
        }
        // 替换表达式为配置值
        matcher.appendReplacement(sb, Matcher.quoteReplacement(value));
    }
    matcher.appendTail(sb);
    return sb.toString();
}

AbstractInterfaceConfig:

protected void checkApplication() {
    // 向后兼容
    if (application == null) {
        // 没有application配置则尝试从系统属性中获取
        String applicationName = ConfigUtils.getProperty("dubbo.application.name");
        if (applicationName != null && applicationName.length() > 0) {
            application = new ApplicationConfig();
        }
    }
    // 没有配置<dubbo:application/>并且系统属性中也没有,则抛出异常
    if (application == null) {
        throw new IllegalStateException(
            "No such application config! Please add <dubbo:application name=\"...\" /> to your spring config.");
    }
    // 追加配置
    appendProperties(application);
    // 如果配置了shutdown wait,设置到系统属性中
    String wait = ConfigUtils.getProperty(Constants.SHUTDOWN_WAIT_KEY);
    if (wait != null && wait.trim().length() > 0) {
        System.setProperty(Constants.SHUTDOWN_WAIT_KEY, wait.trim());
    } else {
        wait = ConfigUtils.getProperty(Constants.SHUTDOWN_WAIT_SECONDS_KEY);
        if (wait != null && wait.trim().length() > 0) {
            System.setProperty(Constants.SHUTDOWN_WAIT_SECONDS_KEY, wait.trim());
        }
    }
}

AbstractInterfaceConfig:

protected void checkRegistry() {
    // 向后兼容
    if (registries == null || registries.size() == 0) {
        // 获取registry配置
        String address = ConfigUtils.getProperty("dubbo.registry.address");
        if (address != null && address.length() > 0) {
            registries = new ArrayList<RegistryConfig>();
            String[] as = address.split("\\s*[|]+\\s*");
            for (String a : as) {
                RegistryConfig registryConfig = new RegistryConfig();
                registryConfig.setAddress(a);
                // 有相关配置,增加到集合中
                registries.add(registryConfig);
            }
        }
    }
    // registry不能为空
    if ((registries == null || registries.size() == 0)) {
        throw new IllegalStateException((getClass().getSimpleName().startsWith("Reference")
            ? "No such any registry to refer service in consumer "
            : "No such any registry to export service in provider ")
        + NetUtils.getLocalHost()
        + " use dubbo version "
        + Version.getVersion()
        + ", Please add <dubbo:registry address=\"...\" /> to your spring config. If you want unregister, please set <dubbo:service registry=\"N/A\" />");
    }
    for (RegistryConfig registryConfig : registries) {
        // 追加配置
        appendProperties(registryConfig);
    }
}

ServiceConfig:

扫描二维码关注公众号,回复: 2986842 查看本文章
private void checkProtocol() {
    if ((protocols == null || protocols.size() == 0)
        && provider != null) {
        setProtocols(provider.getProtocols());
    }
    // 向后兼容
    if (protocols == null || protocols.size() == 0) {
        setProtocol(new ProtocolConfig());
    }
    for (ProtocolConfig protocolConfig : protocols) {
        if (StringUtils.isEmpty(protocolConfig.getName())) {
            protocolConfig.setName("dubbo");
        }
        // 追加配置
        appendProperties(protocolConfig);
    }
}

AbstractInterfaceConfig:

protected void checkStubAndMock(Class<?> interfaceClass) {
    if (ConfigUtils.isNotEmpty(local)) {
        // 缺省类名,即:接口名 + Local后缀
        Class<?> localClass = ConfigUtils.isDefault(local) ? ReflectUtils.forName(interfaceClass.getName() + "Local") : ReflectUtils.forName(local);
        // 必须实现服务接口
        if (!interfaceClass.isAssignableFrom(localClass)) {
            throw new IllegalStateException("The local implementation class " + localClass.getName() + " not implement interface " + interfaceClass.getName());
        }
        try {
            // 构造函数必须允许传入服务对象
            ReflectUtils.findConstructor(localClass, interfaceClass);
        } catch (NoSuchMethodException e) {
            throw new IllegalStateException("No such constructor \"public " + localClass.getSimpleName() + "(" + interfaceClass.getName() + ")\" in local implementation class " + localClass.getName());
        }
    }
    if (ConfigUtils.isNotEmpty(stub)) {
        // 缺省类名,即:接口名 + Stub后缀
        Class<?> localClass = ConfigUtils.isDefault(stub) ? ReflectUtils.forName(interfaceClass.getName() + "Stub") : ReflectUtils.forName(stub);
        // 必须实现服务接口
        if (!interfaceClass.isAssignableFrom(localClass)) {
            throw new IllegalStateException("The local implementation class " + localClass.getName() + " not implement interface " + interfaceClass.getName());
        }
        try {
            // 构造函数必须允许传入服务对象
            ReflectUtils.findConstructor(localClass, interfaceClass);
        } catch (NoSuchMethodException e) {
            throw new IllegalStateException("No such constructor \"public " + localClass.getSimpleName() + "(" + interfaceClass.getName() + ")\" in local implementation class " + localClass.getName());
        }
    }
    if (ConfigUtils.isNotEmpty(mock)) {
        if (mock.startsWith(Constants.RETURN_PREFIX)) {
            String value = mock.substring(Constants.RETURN_PREFIX.length());
            try {
                // 如果是return作为前缀,则解析mock的值(值可以为empty、null、true、false、json字符串等)
                MockInvoker.parseMockValue(value);
            } catch (Exception e) {
                throw new IllegalStateException("Illegal mock json value in <dubbo:service ... mock=\"" + mock + "\" />");
            }
        } else {
            // 缺省类名,即:接口名 + Mock后缀
            Class<?> mockClass = ConfigUtils.isDefault(mock) ? ReflectUtils.forName(interfaceClass.getName() + "Mock") : ReflectUtils.forName(mock);
            // 必须实现服务接口
            if (!interfaceClass.isAssignableFrom(mockClass)) {
                throw new IllegalStateException("The mock implementation class " + mockClass.getName() + " not implement interface " + interfaceClass.getName());
            }
            try {
                // 需要有无参构造函数
                mockClass.getConstructor(new Class<?>[0]);
            } catch (NoSuchMethodException e) {
                throw new IllegalStateException("No such empty constructor \"public " + mockClass.getSimpleName() + "()\" in mock implementation class " + mockClass.getName());
            }
        }
    }
}

ServiceConfig:

private void doExportUrls() {
    /* 加载注册中心配置 */
    List<URL> registryURLs = loadRegistries(true);
    for (ProtocolConfig protocolConfig : protocols) {
        /* 为每个协议暴露服务 */
        doExportUrlsFor1Protocol(protocolConfig, registryURLs);
    }
}

AbstractInterfaceConfig:

protected List<URL> loadRegistries(boolean provider) {
    checkRegistry(); /* 检查registry配置 */
    List<URL> registryList = new ArrayList<URL>();
    if (registries != null && registries.size() > 0) {
        for (RegistryConfig config : registries) {
            String address = config.getAddress();
            if (address == null || address.length() == 0) {
                address = Constants.ANYHOST_VALUE; // 0.0.0.0
            }
            // 获取系统属性的注册中心地址配置
            String sysaddress = System.getProperty("dubbo.registry.address");
            if (sysaddress != null && sysaddress.length() > 0) {
                address = sysaddress;
            }
            if (address != null && address.length() > 0
                && !RegistryConfig.NO_AVAILABLE.equalsIgnoreCase(address)) {
                Map<String, String> map = new HashMap<String, String>();
                /* 追加参数 */
                appendParameters(map, application);
                /* 追加参数 */
                appendParameters(map, config);
                map.put("path", RegistryService.class.getName());
                map.put("dubbo", Version.getVersion());
                map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
                if (ConfigUtils.getPid() > 0) {
                    // 尝试通过java API获取进程id并记录
                    map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));
                }
                if (!map.containsKey("protocol")) {
                    // 判断是否有remote扩展,这里涉及到dubbo SPI的内容,我们会用单独的文章进行分析
                    if (ExtensionLoader.getExtensionLoader(RegistryFactory.class).hasExtension("remote")) {
                        map.put("protocol", "remote");
                    } else {
                        map.put("protocol", "dubbo");
                    }
                }
                /* 解析URL */
                List<URL> urls = UrlUtils.parseURLs(address, map);
                for (URL url : urls) {
                    url = url.addParameter(Constants.REGISTRY_KEY, url.getProtocol());
                    url = url.setProtocol(Constants.REGISTRY_PROTOCOL);
                    if ((provider && url.getParameter(Constants.REGISTER_KEY, true))
                        || (!provider && url.getParameter(Constants.SUBSCRIBE_KEY, true))) {
                        // 添加注册中心地址
                        registryList.add(url);
                    }
                }
            }
        }
    }
    return registryList;
}

AbstractConfig:

protected static void appendParameters(Map<String, String> parameters, Object config) {
    /* 追加参数 */
    appendParameters(parameters, config, null);
}

AbstractConfig:

protected static void appendParameters(Map<String, String> parameters, Object config, String prefix) {
    if (config == null) {
        return;
    }
    Method[] methods = config.getClass().getMethods();
    for (Method method : methods) {
        try {
            String name = method.getName();
            // getter方法,过滤掉getClass方法,public修饰符并且没有参数并且返回值为基本类型(包括String、包装类和Object)
            if ((name.startsWith("get") || name.startsWith("is"))
                && !"getClass".equals(name)
                && Modifier.isPublic(method.getModifiers())
                && method.getParameterTypes().length == 0
                && isPrimitive(method.getReturnType())) {
                Parameter parameter = method.getAnnotation(Parameter.class);
                // 忽略返回值类型为Object或注解excluded属性设置为true的getter方法
                if (method.getReturnType() == Object.class || parameter != null && parameter.excluded()) {
                    continue;
                }
                int i = name.startsWith("get") ? 3 : 2;
                // 将getter驼峰命名去掉get或is后转成.连接的命名,如getDumpDirectory --> dump.directory
                String prop = StringUtils.camelToSplitName(name.substring(i, i + 1).toLowerCase() + name.substring(i + 1), ".");
                String key;
                // 确定key的值,注解的key属性值优先
                if (parameter != null && parameter.key() != null && parameter.key().length() > 0) {
                    key = parameter.key();
                } else {
                    key = prop;
                }
                // 执行getter方法获取返回值
                Object value = method.invoke(config, new Object[0]);
                String str = String.valueOf(value).trim();
                if (value != null && str.length() > 0) {
                    if (parameter != null && parameter.escaped()) {
                        str = URL.encode(str); // URL编码
                    }
                    if (parameter != null && parameter.append()) {
                        // 注解设置了追加属性,则追加前缀
                        String pre = (String) parameters.get(Constants.DEFAULT_KEY + "." + key);
                        if (pre != null && pre.length() > 0) {
                            str = pre + "," + str;
                        }
                        pre = (String) parameters.get(key);
                        if (pre != null && pre.length() > 0) {
                            str = pre + "," + str;
                        }
                    }
                    if (prefix != null && prefix.length() > 0) {
                        key = prefix + "." + key;
                    }
                    // 设置参数映射
                    parameters.put(key, str);
                } else if (parameter != null && parameter.required()) {
                    throw new IllegalStateException(config.getClass().getSimpleName() + "." + key + " == null");
                }
            // getParameters方法
            } else if ("getParameters".equals(name)
                && Modifier.isPublic(method.getModifiers())
                && method.getParameterTypes().length == 0
                && method.getReturnType() == Map.class) {
                // 执行方法获取返回值
                Map<String, String> map = (Map<String, String>) method.invoke(config, new Object[0]);
                if (map != null && map.size() > 0) {
                    String pre = (prefix != null && prefix.length() > 0 ? prefix + "." : "");
                    for (Map.Entry<String, String> entry : map.entrySet()) {
                        // 将key的-替换为.并追加指定的前缀,重新设置参数映射
                        parameters.put(pre + entry.getKey().replace('-', '.'), entry.getValue());
                    }
                }
            }
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }
}

UrlUtils:

public static List<URL> parseURLs(String address, Map<String, String> defaults) {
    if (address == null || address.length() == 0) {
        return null;
    }
    // 分割地址
    String[] addresses = Constants.REGISTRY_SPLIT_PATTERN.split(address);
    if (addresses == null || addresses.length == 0) {
        return null;
    }
    List<URL> registries = new ArrayList<URL>();
    for (String addr : addresses) {
        registries.add(parseURL(addr, defaults));
    }
    return registries;
}

UrlUtils:

public static URL parseURL(String address, Map<String, String> defaults) {
    if (address == null || address.length() == 0) {
        return null;
    }
    String url;
    if (address.indexOf(":// ") >= 0) {
        url = address;
    } else {
        String[] addresses = Constants.COMMA_SPLIT_PATTERN.split(address);
        url = addresses[0];
        if (addresses.length > 1) {
            StringBuilder backup = new StringBuilder();
            for (int i = 1; i < addresses.length; i++) {
                if (i > 1) {
                    backup.append(",");
                }
                backup.append(addresses[i]);
            }
            // 设置backup,如192.168.1.1,192.168.1.2 --> 192.168.1.1?backup=192.168.1.2
            url += "?" + Constants.BACKUP_KEY + "=" + backup.toString();
        }
    }
    String defaultProtocol = defaults == null ? null : defaults.get("protocol");
    if (defaultProtocol == null || defaultProtocol.length() == 0) {
        defaultProtocol = "dubbo"; // 默认协议为dubbo
    }
    // 获取一些默认配置
    String defaultUsername = defaults == null ? null : defaults.get("username");
    String defaultPassword = defaults == null ? null : defaults.get("password");
    int defaultPort = StringUtils.parseInteger(defaults == null ? null : defaults.get("port"));
    String defaultPath = defaults == null ? null : defaults.get("path");
    Map<String, String> defaultParameters = defaults == null ? null : new HashMap<String, String>(defaults);
    if (defaultParameters != null) {
        defaultParameters.remove("protocol");
        defaultParameters.remove("username");
        defaultParameters.remove("password");
        defaultParameters.remove("host");
        defaultParameters.remove("port");
        defaultParameters.remove("path");
    }
    URL u = URL.valueOf(url); // 将url解析成URL对象
    boolean changed = false;
    String protocol = u.getProtocol();
    String username = u.getUsername();
    String password = u.getPassword();
    String host = u.getHost();
    int port = u.getPort();
    String path = u.getPath();
    Map<String, String> parameters = new HashMap<String, String>(u.getParameters());
    // 判断几个属性的值是否为空,如果为空赋为默认值
    if ((protocol == null || protocol.length() == 0) && defaultProtocol != null && defaultProtocol.length() > 0) {
        changed = true;
        protocol = defaultProtocol;
    }
    if ((username == null || username.length() == 0) && defaultUsername != null && defaultUsername.length() > 0) {
        changed = true;
        username = defaultUsername;
    }
    if ((password == null || password.length() == 0) && defaultPassword != null && defaultPassword.length() > 0) {
        changed = true;
        password = defaultPassword;
    }
    if (port <= 0) {
        if (defaultPort > 0) {
            changed = true;
            port = defaultPort;
        } else {
            changed = true;
            port = 9090;
        }
    }
    if (path == null || path.length() == 0) {
        if (defaultPath != null && defaultPath.length() > 0) {
            changed = true;
            path = defaultPath;
        }
    }
    if (defaultParameters != null && defaultParameters.size() > 0) {
        for (Map.Entry<String, String> entry : defaultParameters.entrySet()) {
            String key = entry.getKey();
            String defaultValue = entry.getValue();
            if (defaultValue != null && defaultValue.length() > 0) {
                String value = parameters.get(key);
                if (value == null || value.length() == 0) {
                    changed = true;
                    parameters.put(key, defaultValue);
                }
            }
        }
    }
    if (changed) {
        // 如果属性值有改变,则用新的属性值构建新的URL对象
        u = new URL(protocol, username, password, host, port, path, parameters);
    }
    return u;
}

ServiceConfig:

private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
    String name = protocolConfig.getName();
    if (name == null || name.length() == 0) {
        name = "dubbo";
    }
    Map<String, String> map = new HashMap<String, String>();
    map.put(Constants.SIDE_KEY, Constants.PROVIDER_SIDE);
    map.put(Constants.DUBBO_VERSION_KEY, Version.getVersion());
    map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
    if (ConfigUtils.getPid() > 0) {
        map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));
    }
    // 为几个配置追加参数
    appendParameters(map, application);
    appendParameters(map, module);
    appendParameters(map, provider, Constants.DEFAULT_KEY);
    appendParameters(map, protocolConfig);
    appendParameters(map, this);
    // method配置
    if (methods != null && methods.size() > 0) {
        for (MethodConfig method : methods) {
            // 追加参数
            appendParameters(map, method, method.getName());
            String retryKey = method.getName() + ".retry";
            // retry设置
            if (map.containsKey(retryKey)) {
                String retryValue = map.remove(retryKey);
                if ("false".equals(retryValue)) {
                    map.put(method.getName() + ".retries", "0");
                }
            }
            List<ArgumentConfig> arguments = method.getArguments();
            // 转换参数类型
            if (arguments != null && arguments.size() > 0) {
                for (ArgumentConfig argument : arguments) {
                    if (argument.getType() != null && argument.getType().length() > 0) {
                        Method[] methods = interfaceClass.getMethods();
                        if (methods != null && methods.length > 0) {
                            // 遍历接口的所有方法
                            for (int i = 0; i < methods.length; i++) {
                                String methodName = methods[i].getName();
                                // 目标方法和签名
                                if (methodName.equals(method.getName())) {
                                    Class<?>[] argtypes = methods[i].getParameterTypes();
                                    // 参数索引-1表示未设置
                                    if (argument.getIndex() != -1) {
                                        if (argtypes[argument.getIndex()].getName().equals(argument.getType())) {
                                            // 追加参数
                                            appendParameters(map, argument, method.getName() + "." + argument.getIndex());
                                        } else {
                                            throw new IllegalArgumentException("argument config error : the index attribute and type attribute not match :index :" + argument.getIndex() + ", type:" + argument.getType());
                                        }
                                    } else {
                                        // 方法中的多个回调
                                        for (int j = 0; j < argtypes.length; j++) {
                                            Class<?> argclazz = argtypes[j];
                                            if (argclazz.getName().equals(argument.getType())) {
                                                appendParameters(map, argument, method.getName() + "." + j);
                                                if (argument.getIndex() != -1 && argument.getIndex() != j) {
                                                    throw new IllegalArgumentException("argument config error : the index attribute and type attribute not match :index :" + argument.getIndex() + ", type:" + argument.getType());
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    } else if (argument.getIndex() != -1) {
                        appendParameters(map, argument, method.getName() + "." + argument.getIndex());
                    } else {
                        throw new IllegalArgumentException("argument config must set index or type attribute.eg: <dubbo:argument index='0' .../> or <dubbo:argument type=xxx .../>");
                    }
                }
            }
        }
    }
    // 判断服务是否是GenericService类型
    if (ProtocolUtils.isGeneric(generic)) {
        map.put("generic", generic);
        map.put("methods", Constants.ANY_VALUE);
    } else {
        String revision = Version.getVersion(interfaceClass, version);
        if (revision != null && revision.length() > 0) {
            map.put("revision", revision);
        }
        // 使用javaassist生成接口的包装类,获取方法名称
        String[] methods = Wrapper.getWrapper(interfaceClass).getMethodNames();
        if (methods.length == 0) {
            logger.warn("NO method found in service interface " + interfaceClass.getName());
            map.put("methods", Constants.ANY_VALUE);
        } else {
            map.put("methods", StringUtils.join(new HashSet<String>(Arrays.asList(methods)), ","));
        }
    }
    // token配置
    if (!ConfigUtils.isEmpty(token)) {
        if (ConfigUtils.isDefault(token)) {
            map.put("token", UUID.randomUUID().toString());
        } else {
            map.put("token", token);
        }
    }
    // 协议的名称配置为injvm
    if ("injvm".equals(protocolConfig.getName())) {
        protocolConfig.setRegister(false);
        map.put("notify", "false");
    }
    // contextPath配置
    String contextPath = protocolConfig.getContextpath();
    if ((contextPath == null || contextPath.length() == 0) && provider != null) {
        contextPath = provider.getContextpath();
    }
    /* 注册并绑定服务提供者的IP地址,可以单独配置 */
    String host = this.findConfigedHosts(protocolConfig, registryURLs, map);
    /* 为提供者注册端口和绑定端口,可以单独配置 */
    Integer port = this.findConfigedPorts(protocolConfig, name, map);
    URL url = new URL(name, host, port, (contextPath == null || contextPath.length() == 0 ? "" : contextPath + "/") + path, map);
    if (ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
        .hasExtension(url.getProtocol())) {
        url = ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
        .getExtension(url.getProtocol()).getConfigurator(url).configure(url);
    }
    String scope = url.getParameter(Constants.SCOPE_KEY);
    // scope配置为none不暴露服务
    if (!Constants.SCOPE_NONE.toString().equalsIgnoreCase(scope)) {
        if (!Constants.SCOPE_REMOTE.toString().equalsIgnoreCase(scope)) {
            /* 没有配置为remote,暴露本地服务 */
            exportLocal(url);
        }
        // 没有配置为local,暴露远程服务
        if (!Constants.SCOPE_LOCAL.toString().equalsIgnoreCase(scope)) {
            if (logger.isInfoEnabled()) {
                logger.info("Export dubbo service " + interfaceClass.getName() + " to url " + url);
            }
            // 判断是否有注册中心配置
            if (registryURLs != null && registryURLs.size() > 0) {
                for (URL registryURL : registryURLs) {
                    url = url.addParameterIfAbsent("dynamic", registryURL.getParameter("dynamic"));
                    // 加载监视器地址
                    URL monitorUrl = loadMonitor(registryURL);
                    if (monitorUrl != null) {
                        url = url.addParameterAndEncoded(Constants.MONITOR_KEY, monitorUrl.toFullString());
                    }
                    if (logger.isInfoEnabled()) {
                        logger.info("Register dubbo service " + interfaceClass.getName() + " url " + url + " to registry " + registryURL);
                    }
                    // 获取invoker
                    Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));
                    DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);
                    /* 暴露服务 */
                    Exporter<?> exporter = protocol.export(wrapperInvoker);
                    exporters.add(exporter);
                }
            } else {
                Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url);
                DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);
                Exporter<?> exporter = protocol.export(wrapperInvoker);
                exporters.add(exporter);
            }
        }
    }
    this.urls.add(url);
}

ServiceConfig:

private String findConfigedHosts(ProtocolConfig protocolConfig, List<URL> registryURLs, Map<String, String> map) {
    boolean anyhost = false;
    // 从系统属性中获取dubbo ip绑定配置,如果是非法ip(空、localhost、0.0.0.0、127.*.*.*都属于非法),抛出异常
    String hostToBind = getValueFromConfig(protocolConfig, Constants.DUBBO_IP_TO_BIND);
    // 如果从环境中没有获取到配置,继续寻找
    if (hostToBind != null && hostToBind.length() > 0 && isInvalidLocalHost(hostToBind)) {
        throw new IllegalArgumentException("Specified invalid bind ip from property:" + Constants.DUBBO_IP_TO_BIND + ", value:" + hostToBind);
    }
    if (hostToBind == null || hostToBind.length() == 0) {
        hostToBind = protocolConfig.getHost(); // 从协议配置中获取
        if (provider != null && (hostToBind == null || hostToBind.length() == 0)) {
            // 到这里没有找到则再次尝试从provider配置中获取
            hostToBind = provider.getHost();
        }
        if (isInvalidLocalHost(hostToBind)) {
            anyhost = true;
            try {
                // 如果到这里获取的ip为空或者非法,则尝试赋值为本地主机地址
                hostToBind = InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
                logger.warn(e.getMessage(), e);
            }
            if (isInvalidLocalHost(hostToBind)) {
                if (registryURLs != null && registryURLs.size() > 0) {
                    for (URL registryURL : registryURLs) {
                        try {
                            Socket socket = new Socket();
                            try {
                                SocketAddress addr = new InetSocketAddress(registryURL.getHost(), registryURL.getPort());
                                socket.connect(addr, 1000);
                                hostToBind = socket.getLocalAddress().getHostAddress();
                                break;
                            } finally {
                                try {
                                    socket.close();
                                } catch (Throwable e) {
                                }
                            }
                        } catch (Exception e) {
                            logger.warn(e.getMessage(), e);
                        }
                    }
                }
                if (isInvalidLocalHost(hostToBind)) {
                    // 如果到这里获取的ip还是为空或者非法,则尝试从本地网卡查找第一个有效的IP,如果没有获取到,则赋值为127.0.0.1
                    hostToBind = getLocalHost();
                }
            }
        }
    }
    map.put(Constants.BIND_IP_KEY, hostToBind);
    // 尝试从系统属性中获取注册中心ip配置
    String hostToRegistry = getValueFromConfig(protocolConfig, Constants.DUBBO_IP_TO_REGISTRY);
    if (hostToRegistry != null && hostToRegistry.length() > 0 && isInvalidLocalHost(hostToRegistry)) {
        throw new IllegalArgumentException("Specified invalid registry ip from property:" + Constants.DUBBO_IP_TO_REGISTRY + ", value:" + hostToRegistry);
    } else if (hostToRegistry == null || hostToRegistry.length() == 0) {
        // 没有从系统环境中获取到则赋值为绑定的ip
        hostToRegistry = hostToBind;
    }
    map.put(Constants.ANYHOST_KEY, String.valueOf(anyhost));
    return hostToRegistry;
}

ServiceConfig:

private Integer findConfigedPorts(ProtocolConfig protocolConfig, String name, Map<String, String> map) {
    Integer portToBind = null;
    // 从系统环境中解析绑定的端口
    String port = getValueFromConfig(protocolConfig, Constants.DUBBO_PORT_TO_BIND);
    // 将端口转换成int类型并判断是否合法(在0-65535范围之内)
    portToBind = parsePort(port);
    // 如果没有找到绑定端口的配置,继续寻找
    if (portToBind == null) {
        // 从protocol配置中寻找
        portToBind = protocolConfig.getPort();
        if (provider != null && (portToBind == null || portToBind == 0)) {
            // 从provider配置中寻找
            portToBind = provider.getPort();
        }
        // 默认protocol配置中寻找
        final int defaultPort = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(name).getDefaultPort();
        if (portToBind == null || portToBind == 0) {
            portToBind = defaultPort;
        }
        if (portToBind == null || portToBind <= 0) {
            // 获取随机端口,从缓存中获取,缓存中没有会返回Integer.MIN
            portToBind = getRandomPort(name);
            if (portToBind == null || portToBind < 0) {
                // 获取可用端口
                portToBind = getAvailablePort(defaultPort);
                // 放入缓存
                putRandomPort(name, portToBind);
            }
            logger.warn("Use random available port(" + portToBind + ") for protocol " + name);
        }
    }
    map.put(Constants.BIND_PORT_KEY, String.valueOf(portToBind));
    // 注册中心端口,默认情况下不用作绑定端口
    String portToRegistryStr = getValueFromConfig(protocolConfig, Constants.DUBBO_PORT_TO_REGISTRY);
    Integer portToRegistry = parsePort(portToRegistryStr);
    if (portToRegistry == null) {
        portToRegistry = portToBind;
    }
    return portToRegistry;
}

ServiceConfig:

private void exportLocal(URL url) {
    // 判断协议是否不是injvm
    if (!Constants.LOCAL_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {
        URL local = URL.valueOf(url.toFullString())
        .setProtocol(Constants.LOCAL_PROTOCOL) // 设置injvm协议
        .setHost(LOCALHOST) // 127.0.0.1
        .setPort(0);
        ServiceClassHolder.getInstance().pushServiceClass(getServiceClass(ref));
        /* 获取invoker,暴露服务 */
        Exporter<?> exporter = protocol.export(
            proxyFactory.getInvoker(ref, (Class) interfaceClass, local));
        exporters.add(exporter); // 添加到已暴露的服务列表中
        logger.info("Export dubbo service " + interfaceClass.getName() + " to local registry");
    }
}

JavassistProxyFactory:

public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
    // 包装类无法处理类名包含$的类
    final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf('$') < 0 ? proxy.getClass() : type);
    return new AbstractProxyInvoker<T>(proxy, type, url) {
        @Override
        protected Object doInvoke(T proxy, String methodName,
            Class<?>[] parameterTypes,
            Object[] arguments) throws Throwable {
            return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
        }
    };
}

RegistryProtocol:

public <T> Exporter<T> export(final Invoker<T> originInvoker) throws RpcException {
    /* 暴露invoker */
    final ExporterChangeableWrapper<T> exporter = doLocalExport(originInvoker);
    // 从invoker中获取之前构建好的url
    URL registryUrl = getRegistryUrl(originInvoker);
    /* 获取注册中心 */
    final Registry registry = getRegistry(originInvoker);
    // 获取已经注册的提供者的url
    final URL registedProviderUrl = getRegistedProviderUrl(originInvoker);
    // 判断是否延迟发布
    boolean register = registedProviderUrl.getParameter("register", true);
    // 将提供者注册到提供者消费者注册表中
    ProviderConsumerRegTable.registerProvider(originInvoker, registryUrl, registedProviderUrl);
    if (register) {
        /* 注册提供者 */
        register(registryUrl, registedProviderUrl);
        // 将提供者消费者注册表的相关提供者设置为已注册
        ProviderConsumerRegTable.getProviderWrapper(originInvoker).setReg(true);
    }
    // 获取订阅覆盖数据的url
    final URL overrideSubscribeUrl = getSubscribedOverrideUrl(registedProviderUrl);
    // 覆盖监听器
    final OverrideListener overrideSubscribeListener = new OverrideListener(overrideSubscribeUrl, originInvoker);
    overrideListeners.put(overrideSubscribeUrl, overrideSubscribeListener);
    /* 订阅 */
    registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener);
    // 确保每次暴露都会返回一个新的实例
    return new Exporter<T>() {
        public Invoker<T> getInvoker() {
            return exporter.getInvoker();
        }
        public void unexport() {
            try {
                exporter.unexport();
            } catch (Throwable t) {
                logger.warn(t.getMessage(), t);
            }
            try {
                registry.unregister(registedProviderUrl);
            } catch (Throwable t) {
                logger.warn(t.getMessage(), t);
            }
            try {
                overrideListeners.remove(overrideSubscribeUrl);
                registry.unsubscribe(overrideSubscribeUrl, overrideSubscribeListener);
            } catch (Throwable t) {
                logger.warn(t.getMessage(), t);
            }
        }
    };
}

RegistryProtocol:

private <T> ExporterChangeableWrapper<T> doLocalExport(final Invoker<T> originInvoker) {
    String key = getCacheKey(originInvoker); // 缓存key,就是providerUrl
    // bounds为providerurl和exporter的映射,目的是为了解决RMI重复出现端口冲突的问题,已经暴露的服务不再暴露。
    ExporterChangeableWrapper<T> exporter = (ExporterChangeableWrapper<T>) bounds.get(key);
    if (exporter == null) {
        synchronized (bounds) {
            exporter = (ExporterChangeableWrapper<T>) bounds.get(key);
            if (exporter == null) {
                final Invoker<?> invokerDelegete = new InvokerDelegete<T>(originInvoker, getProviderUrl(originInvoker));
                /* 暴露服务 */
                exporter = new ExporterChangeableWrapper<T>((Exporter<T>) protocol.export(invokerDelegete), originInvoker);
                bounds.put(key, exporter);
            }
        }
    }
    return exporter;
}

DubboProtocol:

public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
    URL url = invoker.getUrl();
    String key = serviceKey(url); // 格式(分组/接口全称:服务版本:端口),接口和端口是一定存在的,分组和服务版本不一定
    DubboExporter<T> exporter = new DubboExporter<T>(invoker, key, exporterMap);
    exporterMap.put(key, exporter);
    // 是否为调度事件暴露一个stub服务
    Boolean isStubSupportEvent = url.getParameter(Constants.STUB_EVENT_KEY, Constants.DEFAULT_STUB_EVENT);
    Boolean isCallbackservice = url.getParameter(Constants.IS_CALLBACK_SERVICE, false);
    if (isStubSupportEvent && !isCallbackservice) {
        String stubServiceMethods = url.getParameter(Constants.STUB_EVENT_METHODS_KEY);
        if (stubServiceMethods == null || stubServiceMethods.length() == 0) {
            if (logger.isWarnEnabled()) {
                logger.warn(new IllegalStateException("consumer [" + url.getParameter(Constants.INTERFACE_KEY) +
                    "], has set stubproxy support event ,but no stub methods founded."));
            }
        } else {
            stubServiceMethodsMap.put(url.getServiceKey(), stubServiceMethods);
        }
    }
    /* 开启服务 */
    openServer(url);
    optimizeSerialization(url); // 优化序列化
    return exporter;
}

DubboProtocol:

private void openServer(URL url) {
    String key = url.getAddress();
    // 客户端可以暴露仅用于服务端调用的服务
    boolean isServer = url.getParameter(Constants.IS_SERVER_KEY, true);
    if (isServer) {
        ExchangeServer server = serverMap.get(key);
        if (server == null) {
            /* 创建服务 */
            serverMap.put(key, createServer(url));
        } else {
            // 服务端支持重置,与重写一起使用
            server.reset(url);
        }
    }
}

DubboProtocol:

private ExchangeServer createServer(URL url) {
    // 当服务器关闭时发送只读事件,默认为true
    url = url.addParameterIfAbsent(Constants.CHANNEL_READONLYEVENT_SENT_KEY, Boolean.TRUE.toString());
    // 默认启用心跳
    url = url.addParameterIfAbsent(Constants.HEARTBEAT_KEY, String.valueOf(Constants.DEFAULT_HEARTBEAT));
    // server,默认为netty
    String str = url.getParameter(Constants.SERVER_KEY, Constants.DEFAULT_REMOTING_SERVER);
    if (str != null && str.length() > 0 && !ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(str))
        throw new RpcException("Unsupported server type: " + str + ", url: " + url);
    url = url.addParameter(Constants.CODEC_KEY, DubboCodec.NAME);
    ExchangeServer server;
    try {
        /* 绑定 */
        server = Exchangers.bind(url, requestHandler);
    } catch (RemotingException e) {
        throw new RpcException("Fail to start server(url: " + url + ") " + e.getMessage(), e);
    }
    str = url.getParameter(Constants.CLIENT_KEY);
    if (str != null && str.length() > 0) {
        Set<String> supportedTypes = ExtensionLoader.getExtensionLoader(Transporter.class).getSupportedExtensions();
        if (!supportedTypes.contains(str)) {
            throw new RpcException("Unsupported client type: " + str);
        }
    }
    return server;
}

Exchangers:

public static ExchangeServer bind(URL url, ExchangeHandler handler) throws RemotingException {
    if (url == null) {
        throw new IllegalArgumentException("url == null");
    }
    if (handler == null) {
        throw new IllegalArgumentException("handler == null");
    }
    url = url.addParameterIfAbsent(Constants.CODEC_KEY, "exchange");
    /* 获取exchanger(默认为HeaderExchanger),绑定 */
    return getExchanger(url).bind(url, handler);
}

HeaderExchanger:

public ExchangeServer bind(URL url, ExchangeHandler handler) throws RemotingException {
    /* 绑定,构建server */
    return new HeaderExchangeServer(Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler))));
}

Transporters:

public static Server bind(URL url, ChannelHandler... handlers) throws RemotingException {
    if (url == null) {
        throw new IllegalArgumentException("url == null");
    }
    if (handlers == null || handlers.length == 0) {
        throw new IllegalArgumentException("handlers == null");
    }
    ChannelHandler handler;
    if (handlers.length == 1) {
        handler = handlers[0];
    } else {
        handler = new ChannelHandlerDispatcher(handlers);
    }
    /* 获取Transporter,绑定 */
    return getTransporter().bind(url, handler);
}

NettyTransporter:

public Server bind(URL url, ChannelHandler listener) throws RemotingException {
    /* 构建NettyServer */
    return new NettyServer(url, listener);
}

NettyServer:

public NettyServer(URL url, ChannelHandler handler) throws RemotingException {
    /* 为url设置线程名称,包装handler,调用父类构造方法初始化 */
    super(url, ChannelHandlers.wrap(handler, ExecutorUtil.setThreadName(url, SERVER_THREAD_POOL_NAME)));
}

AbstractServer:

public AbstractServer(URL url, ChannelHandler handler) throws RemotingException {
    super(url, handler);
    localAddress = getUrl().toInetSocketAddress();
    String bindIp = getUrl().getParameter(Constants.BIND_IP_KEY, getUrl().getHost()); // ip
    int bindPort = getUrl().getParameter(Constants.BIND_PORT_KEY, getUrl().getPort()); // 端口
    if (url.getParameter(Constants.ANYHOST_KEY, false) || NetUtils.isInvalidLocalHost(bindIp)) {
        bindIp = NetUtils.ANYHOST;
    }
    bindAddress = new InetSocketAddress(bindIp, bindPort); // 绑定地址
    this.accepts = url.getParameter(Constants.ACCEPTS_KEY, Constants.DEFAULT_ACCEPTS);
    this.idleTimeout = url.getParameter(Constants.IDLE_TIMEOUT_KEY, Constants.DEFAULT_IDLE_TIMEOUT);
    try {
        doOpen(); /* 开启服务 */
        if (logger.isInfoEnabled()) {
            logger.info("Start " + getClass().getSimpleName() + " bind " + getBindAddress() + ", export " + getLocalAddress());
        }
    } catch (Throwable t) {
        throw new RemotingException(url.toInetSocketAddress(), null, "Failed to bind " + getClass().getSimpleName()
            + " on " + getLocalAddress() + ", cause: " + t.getMessage(), t);
    }
    DataStore dataStore = ExtensionLoader.getExtensionLoader(DataStore.class).getDefaultExtension();
    executor = (ExecutorService) dataStore.get(Constants.EXECUTOR_SERVICE_COMPONENT_KEY, Integer.toString(url.getPort()));
}

NettyServer:

protected void doOpen() throws Throwable {
    NettyHelper.setNettyLoggerFactory();
    ExecutorService boss = Executors.newCachedThreadPool(new NamedThreadFactory("NettyServerBoss", true)); // boss线程池
    ExecutorService worker = Executors.newCachedThreadPool(new NamedThreadFactory("NettyServerWorker", true)); // worker线程池
    ChannelFactory channelFactory = new NioServerSocketChannelFactory(boss, worker, getUrl().getPositiveParameter(Constants.IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS));
    bootstrap = new ServerBootstrap(channelFactory);
    final NettyHandler nettyHandler = new NettyHandler(getUrl(), this);
    channels = nettyHandler.getChannels();
    bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
        public ChannelPipeline getPipeline() {
            NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyServer.this);
            ChannelPipeline pipeline = Channels.pipeline();
            pipeline.addLast("decoder", adapter.getDecoder()); // 解码器
            pipeline.addLast("encoder", adapter.getEncoder()); // 编码器
            pipeline.addLast("handler", nettyHandler); // 处理器
            return pipeline;
        }
    });
    // 绑定
    channel = bootstrap.bind(getBindAddress());
}

这我们看到了dubbo使用netty来开启服务,需要读者对netty的知识有一定的了解,这里使用的是netty3,dubbo目前已经有netty4的使用,在com.alibaba.dubbo.remoting.transport.netty4包下。服务暴露之后,下面就到了注册中心的部分了,我们会用单独的文章来分析注册中心的相关内容。

到这里,整个服务的暴露就完成了,我们是从本地服务暴露开始分析的,用了很大篇幅来讲解这个过程,远程服务暴露也是同样复用这个流程。到这里,整个dubbo服务提供者的源码分析就完成了。

猜你喜欢

转载自blog.csdn.net/heroqiang/article/details/79189798