This is an automated email from the ASF dual-hosted git repository.

iluo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo.git


The following commit(s) were added to refs/heads/master by this push:
     new 95ebfe8  add java doc to dubbo-config-api (#3103)
95ebfe8 is described below

commit 95ebfe8b5a93942d3c3928ad5e9cd4709c76886a
Author: XiaoJie Li <[email protected]>
AuthorDate: Wed Jan 2 20:40:23 2019 +0800

    add java doc to dubbo-config-api (#3103)
    
    * add config-api javadoc
    
    * add dubbo-config-api javadoc
    
    * update javadoc
    
    * add dubbo-config-api java doc
---
 .../org/apache/dubbo/config/AbstractConfig.java    |   44 +
 .../dubbo/config/AbstractInterfaceConfig.java      | 1454 ++++++++++----------
 .../apache/dubbo/config/AbstractMethodConfig.java  |   52 +-
 .../dubbo/config/AbstractReferenceConfig.java      |   37 +-
 .../apache/dubbo/config/AbstractServiceConfig.java |   61 +-
 .../org/apache/dubbo/config/ApplicationConfig.java |   70 +-
 .../org/apache/dubbo/config/ArgumentConfig.java    |   14 +-
 .../org/apache/dubbo/config/ConsumerConfig.java    |   28 +-
 .../apache/dubbo/config/MetadataReportConfig.java  |   14 +-
 .../java/org/apache/dubbo/config/MethodConfig.java |   61 +-
 .../java/org/apache/dubbo/config/ModuleConfig.java |   32 +-
 .../org/apache/dubbo/config/MonitorConfig.java     |   23 +-
 .../org/apache/dubbo/config/ProtocolConfig.java    |  126 +-
 .../org/apache/dubbo/config/ProviderConfig.java    |   96 +-
 .../org/apache/dubbo/config/ReferenceConfig.java   |   72 +-
 .../org/apache/dubbo/config/RegistryConfig.java    |   70 +-
 .../org/apache/dubbo/config/ServiceConfig.java     |   74 +-
 .../invoker/DelegateProviderMetaDataInvoker.java   |    4 +
 .../dubbo/config/utils/ReferenceConfigCache.java   |    2 +-
 .../dubbo/monitor/support/MonitorFilter.java       |   99 +-
 .../apache/dubbo/monitor/dubbo/DubboMonitor.java   |   20 +-
 21 files changed, 1523 insertions(+), 930 deletions(-)

diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractConfig.java
index a719c74..6394097 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractConfig.java
@@ -50,22 +50,55 @@ public abstract class AbstractConfig implements 
Serializable {
 
     protected static final Logger logger = 
LoggerFactory.getLogger(AbstractConfig.class);
     private static final long serialVersionUID = 4267533505537413570L;
+
+    /**
+     * The maximum length of a <b>parameter's value</b>
+     */
     private static final int MAX_LENGTH = 200;
 
+    /**
+     * The maximum length of a <b>path</b>
+     */
     private static final int MAX_PATH_LENGTH = 200;
 
+    /**
+     * The rule qualification for <b>name</b>
+     */
     private static final Pattern PATTERN_NAME = 
Pattern.compile("[\\-._0-9a-zA-Z]+");
 
+    /**
+     * The rule qualification for <b>multiply name</b>
+     */
     private static final Pattern PATTERN_MULTI_NAME = 
Pattern.compile("[,\\-._0-9a-zA-Z]+");
 
+    /**
+     * The rule qualification for <b>method names</b>
+     */
     private static final Pattern PATTERN_METHOD_NAME = 
Pattern.compile("[a-zA-Z][0-9a-zA-Z]*");
 
+    /**
+     * The rule qualification for <b>path</b>
+     */
     private static final Pattern PATTERN_PATH = 
Pattern.compile("[/\\-$._0-9a-zA-Z]+");
 
+    /**
+     * The pattern matches a value who has a symbol
+     */
     private static final Pattern PATTERN_NAME_HAS_SYMBOL = 
Pattern.compile("[:*,\\s/\\-._0-9a-zA-Z]+");
 
+    /**
+     * The pattern matches a property key
+     */
     private static final Pattern PATTERN_KEY = 
Pattern.compile("[*,\\-._0-9a-zA-Z]+");
+
+    /**
+     * The legacy properties container
+     */
     private static final Map<String, String> legacyProperties = new 
HashMap<String, String>();
+
+    /**
+     * The suffix container
+     */
     private static final String[] SUFFIXES = new String[]{"Config", "Bean"};
 
     static {
@@ -82,6 +115,9 @@ public abstract class AbstractConfig implements Serializable 
{
         DubboShutdownHook.getDubboShutdownHook().register();
     }
 
+    /**
+     * The config id
+     */
     protected String id;
     protected String prefix;
 
@@ -278,6 +314,14 @@ public abstract class AbstractConfig implements 
Serializable {
         }
     }
 
+    /**
+     * Check whether there is a <code>Extension</code> who's name (property) 
is <code>value</code> (special treatment is
+     * required)
+     *
+     * @param type The Extension type
+     * @param property The extension key
+     * @param value The Extension name
+     */
     protected static void checkMultiExtension(Class<?> type, String property, 
String value) {
         checkMultiName(property, value);
         if (StringUtils.isNotEmpty(value)) {
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
index 8eb6df6..051e26e 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
@@ -1,692 +1,762 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.config;
-
-import org.apache.dubbo.common.Constants;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.Version;
-import org.apache.dubbo.common.config.Environment;
-import org.apache.dubbo.common.utils.Assert;
-import org.apache.dubbo.common.utils.ConfigUtils;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.common.utils.ReflectUtils;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.common.utils.UrlUtils;
-import org.apache.dubbo.config.support.Parameter;
-import org.apache.dubbo.metadata.integration.MetadataReportService;
-import org.apache.dubbo.monitor.MonitorFactory;
-import org.apache.dubbo.monitor.MonitorService;
-import org.apache.dubbo.registry.RegistryService;
-import org.apache.dubbo.rpc.Filter;
-import org.apache.dubbo.rpc.InvokerListener;
-import org.apache.dubbo.rpc.ProxyFactory;
-import org.apache.dubbo.rpc.cluster.Cluster;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.support.MockInvoker;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static org.apache.dubbo.common.Constants.APPLICATION_KEY;
-import static 
org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
-
-/**
- * AbstractDefaultConfig
- *
- * @export
- */
-public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
-
-    private static final long serialVersionUID = -1559314110797223229L;
-
-    // local impl class name for the service interface
-    protected String local;
-
-    // local stub class name for the service interface
-    protected String stub;
-
-    // service monitor
-    protected MonitorConfig monitor;
-
-    // proxy type
-    protected String proxy;
-
-    // cluster type
-    protected String cluster;
-
-    // filter
-    protected String filter;
-
-    // listener
-    protected String listener;
-
-    // owner
-    protected String owner;
-
-    // connection limits, 0 means shared connection, otherwise it defines the 
connections delegated to the
-    // current service
-    protected Integer connections;
-
-    // layer
-    protected String layer;
-
-    // application info
-    protected ApplicationConfig application;
-
-    // module info
-    protected ModuleConfig module;
-
-    // registry centers
-    protected List<RegistryConfig> registries;
-
-    protected String registryIds;
-
-    // connection events
-    protected String onconnect;
-
-    // disconnection events
-    protected String ondisconnect;
-    protected MetadataReportConfig metadataReportConfig;
-    protected RegistryDataConfig registryDataConfig;
-    // callback limits
-    private Integer callbacks;
-    // the scope for referring/exporting a service, if it's local, it means 
searching in current JVM only.
-    private String scope;
-
-    protected void checkRegistry() {
-        loadRegistriesFromBackwardConfig();
-
-        convertRegistryIdsToRegistries();
-
-        for (RegistryConfig registryConfig : registries) {
-            registryConfig.refresh();
-            if (StringUtils.isNotEmpty(registryConfig.getId())) {
-                registryConfig.setPrefix(Constants.REGISTRIES_SUFFIX);
-                registryConfig.refresh();
-            }
-        }
-
-        for (RegistryConfig registryConfig : registries) {
-            if (!registryConfig.isValid()) {
-                throw new IllegalStateException("No registry config found or 
it's not a valid config! " +
-                        "The registry config is: " + registryConfig);
-            }
-        }
-
-        useRegistryForConfigIfNecessary();
-    }
-
-    @SuppressWarnings("deprecation")
-    protected void checkApplication() {
-        // for backward compatibility
-        if (application == null) {
-            application = new ApplicationConfig();
-        }
-
-        application.refresh();
-
-        if (!application.isValid()) {
-            throw new IllegalStateException("No application config found or 
it's not a valid config! " +
-                    "Please add <dubbo:application name=\"...\" /> to your 
spring config.");
-        }
-
-        ApplicationModel.setApplication(application.getName());
-
-        // backward compatibility
-        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());
-            }
-        }
-    }
-
-    protected void checkMonitor() {
-        if (monitor == null) {
-            monitor = new MonitorConfig();
-        }
-
-        monitor.refresh();
-
-        if (!monitor.isValid()) {
-            logger.info("There's no valid monitor config found, if you want to 
open monitor statistics for Dubbo, " +
-                    "please make sure your monitor is configured properly.");
-        }
-    }
-
-    protected void checkMetadataReport() {
-        if (metadataReportConfig == null) {
-            metadataReportConfig = new MetadataReportConfig();
-        }
-        metadataReportConfig.refresh();
-        if (!metadataReportConfig.isValid()) {
-            logger.warn("There's no valid metadata config found, if you are 
using the simplified mode of registry url, " +
-                    "please make sure you have a metadata address configured 
properly.");
-        }
-    }
-
-    protected void checkRegistryDataConfig() {
-        if (registryDataConfig == null) {
-            registryDataConfig = new RegistryDataConfig();
-        }
-        registryDataConfig.refresh();
-        if (!registryDataConfig.isValid()) {
-            logger.info("There's no valid registryData config found. So the 
registry will store full url parameter " +
-                    "to registry server.");
-        }
-    }
-
-    protected List<URL> loadRegistries(boolean provider) {
-        // check && override if necessary
-        checkRegistry();
-        checkRegistryDataConfig();
-        List<URL> registryList = new ArrayList<URL>();
-        if (registries != null && !registries.isEmpty()) {
-            Map<String, String> registryDataConfigurationMap = new 
HashMap<>(4);
-            appendParameters(registryDataConfigurationMap, registryDataConfig);
-            for (RegistryConfig config : registries) {
-                String address = config.getAddress();
-                if (StringUtils.isEmpty(address)) {
-                    address = Constants.ANYHOST_VALUE;
-                }
-                if (!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());
-                    appendRuntimeParameters(map);
-                    if (!map.containsKey("protocol")) {
-                        map.put("protocol", "dubbo");
-                    }
-                    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);
-                        // add parameter
-                        url = 
url.addParametersIfAbsent(registryDataConfigurationMap);
-                        if ((provider && 
url.getParameter(Constants.REGISTER_KEY, true))
-                                || (!provider && 
url.getParameter(Constants.SUBSCRIBE_KEY, true))) {
-                            registryList.add(url);
-                        }
-                    }
-                }
-            }
-        }
-        return registryList;
-    }
-
-    protected URL loadMonitor(URL registryURL) {
-        checkMonitor();
-        Map<String, String> map = new HashMap<String, String>();
-        map.put(Constants.INTERFACE_KEY, MonitorService.class.getName());
-        appendRuntimeParameters(map);
-        //set ip
-        String hostToRegistry = 
ConfigUtils.getSystemProperty(Constants.DUBBO_IP_TO_REGISTRY);
-        if (hostToRegistry == null || hostToRegistry.length() == 0) {
-            hostToRegistry = NetUtils.getLocalHost();
-        } else if (NetUtils.isInvalidLocalHost(hostToRegistry)) {
-            throw new IllegalArgumentException("Specified invalid registry ip 
from property:" +
-                    Constants.DUBBO_IP_TO_REGISTRY + ", value:" + 
hostToRegistry);
-        }
-        map.put(Constants.REGISTER_IP_KEY, hostToRegistry);
-        appendParameters(map, monitor);
-        appendParameters(map, application);
-        String address = monitor.getAddress();
-        String sysaddress = System.getProperty("dubbo.monitor.address");
-        if (sysaddress != null && sysaddress.length() > 0) {
-            address = sysaddress;
-        }
-        if (ConfigUtils.isNotEmpty(address)) {
-            if (!map.containsKey(Constants.PROTOCOL_KEY)) {
-                if 
(getExtensionLoader(MonitorFactory.class).hasExtension("logstat")) {
-                    map.put(Constants.PROTOCOL_KEY, "logstat");
-                } else {
-                    map.put(Constants.PROTOCOL_KEY, Constants.DOBBO_PROTOCOL);
-                }
-            }
-            return UrlUtils.parseURL(address, map);
-        } else if (Constants.REGISTRY_PROTOCOL.equals(monitor.getProtocol()) 
&& registryURL != null) {
-          return 
registryURL.setProtocol(Constants.DOBBO_PROTOCOL).addParameter(Constants.PROTOCOL_KEY,
 Constants.REGISTRY_PROTOCOL).addParameterAndEncoded(Constants.REFER_KEY, 
StringUtils.toQueryString(map));
-        }
-        return null;
-    }
-  
-    static void appendRuntimeParameters(Map<String, String> map) {
-        map.put(Constants.DUBBO_VERSION_KEY, Version.getProtocolVersion());
-        map.put(Constants.SPECIFICATION_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()));
-        }
-    }
-  
-    private URL loadMetadataReporterURL(boolean provider) {
-        this.checkApplication();
-        String address = metadataReportConfig.getAddress();
-        if (address == null || address.length() == 0) {
-            return null;
-        }
-        Map<String, String> map = new HashMap<String, String>();
-        map.put(APPLICATION_KEY, application.getName());
-        appendParameters(map, metadataReportConfig);
-        return UrlUtils.parseURL(address, map);
-    }
-
-    protected MetadataReportService getMetadataReportService() {
-
-        if (metadataReportConfig == null || !metadataReportConfig.isValid()) {
-            return null;
-        }
-        return MetadataReportService.instance(() -> {
-            return loadMetadataReporterURL(true);
-        });
-    }
-
-    protected void checkInterfaceAndMethods(Class<?> interfaceClass, 
List<MethodConfig> methods) {
-        // interface cannot be null
-        Assert.notNull(interfaceClass, new IllegalStateException("interface 
not allow null!"));
-
-        // to verify interfaceClass is an interface
-        if (!interfaceClass.isInterface()) {
-            throw new IllegalStateException("The interface class " + 
interfaceClass + " is not a interface!");
-        }
-        // check if methods exist in the interface
-        if (methods != null && !methods.isEmpty()) {
-            for (MethodConfig methodBean : methods) {
-                methodBean.setService(interfaceClass.getName());
-                methodBean.setServiceId(this.getId());
-                methodBean.refresh();
-                String methodName = methodBean.getName();
-                if (methodName == null || methodName.length() == 0) {
-                    throw new IllegalStateException("<dubbo:method> name 
attribute is required! Please check: " +
-                            "<dubbo:service interface=\"" + 
interfaceClass.getName() + "\" ... >" +
-                            "<dubbo:method name=\"\" ... 
/></<dubbo:reference>");
-                }
-
-                boolean hasMethod = 
Arrays.stream(interfaceClass.getMethods()).anyMatch(method -> 
method.getName().equals(methodName));
-                if (!hasMethod) {
-                    throw new IllegalStateException("The interface " + 
interfaceClass.getName()
-                            + " not found method " + methodName);
-                }
-            }
-        }
-    }
-
-    void checkMock(Class<?> interfaceClass) {
-        if (ConfigUtils.isEmpty(mock)) {
-            return;
-        }
-
-        String normalizedMock = MockInvoker.normalizeMock(mock);
-        if (normalizedMock.startsWith(Constants.RETURN_PREFIX)) {
-            normalizedMock = 
normalizedMock.substring(Constants.RETURN_PREFIX.length()).trim();
-            try {
-                MockInvoker.parseMockValue(normalizedMock);
-            } catch (Exception e) {
-                throw new IllegalStateException("Illegal mock return in 
<dubbo:service/reference ... " +
-                        "mock=\"" + mock + "\" />");
-            }
-        } else if (normalizedMock.startsWith(Constants.THROW_PREFIX)) {
-            normalizedMock = 
normalizedMock.substring(Constants.THROW_PREFIX.length()).trim();
-            if (ConfigUtils.isNotEmpty(normalizedMock)) {
-                try {
-                    MockInvoker.getThrowable(normalizedMock);
-                } catch (Exception e) {
-                    throw new IllegalStateException("Illegal mock throw in 
<dubbo:service/reference ... " +
-                            "mock=\"" + mock + "\" />");
-                }
-            }
-        } else {
-            MockInvoker.getMockObject(normalizedMock, interfaceClass);
-        }
-    }
-
-    void checkStubAndLocal(Class<?> interfaceClass) {
-        if (ConfigUtils.isNotEmpty(local)) {
-            Class<?> localClass = ConfigUtils.isDefault(local) ?
-                    ReflectUtils.forName(interfaceClass.getName() + "Local") : 
ReflectUtils.forName(local);
-            verify(interfaceClass, localClass);
-        }
-        if (ConfigUtils.isNotEmpty(stub)) {
-            Class<?> localClass = ConfigUtils.isDefault(stub) ?
-                    ReflectUtils.forName(interfaceClass.getName() + "Stub") : 
ReflectUtils.forName(stub);
-            verify(interfaceClass, localClass);
-        }
-    }
-
-    private void verify(Class<?> interfaceClass, Class<?> localClass) {
-        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());
-        }
-    }
-
-    private void overrideParameters(Map<String, String> map) {
-        map.put(Constants.PATH_KEY, RegistryService.class.getName());
-        map.put(Constants.DOBBO_PROTOCOL, Version.getProtocolVersion());
-        map.put(Constants.TIMESTAMP_KEY, 
String.valueOf(System.currentTimeMillis()));
-        if (ConfigUtils.getPid() > 0) {
-            map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));
-        }
-        map.putIfAbsent(Constants.PROTOCOL_KEY, Constants.DOBBO_PROTOCOL);
-    }
-
-    private void convertRegistryIdsToRegistries() {
-        if (StringUtils.isEmpty(registryIds) && (registries == null || 
registries.isEmpty())) {
-            Set<String> configedRegistries = new HashSet<>();
-            
configedRegistries.addAll(getSubProperties(Environment.getInstance().getExternalConfigurationMap(),
-                    Constants.REGISTRIES_SUFFIX));
-            
configedRegistries.addAll(getSubProperties(Environment.getInstance().getAppExternalConfigurationMap(),
-                    Constants.REGISTRIES_SUFFIX));
-
-            registryIds = String.join(",", configedRegistries);
-        }
-
-        if (StringUtils.isEmpty(registryIds)) {
-            if (registries == null || registries.isEmpty()) {
-                registries = new ArrayList<>();
-                registries.add(new RegistryConfig());
-            }
-        } else {
-            String[] arr = Constants.COMMA_SPLIT_PATTERN.split(registryIds);
-            if (registries == null || registries.isEmpty()) {
-                registries = new ArrayList<>();
-            }
-            Arrays.stream(arr).forEach(id -> {
-                if (registries.stream().noneMatch(reg -> 
reg.getId().equals(id))) {
-                    RegistryConfig registryConfig = new RegistryConfig();
-                    registryConfig.setId(id);
-                    registries.add(registryConfig);
-                }
-            });
-            if (registries.size() > arr.length) {
-                throw new IllegalStateException("Too much registries found, 
the registries assigned to this service " +
-                        "are :" + registryIds + ", but got " + 
registries.size() + " registries!");
-            }
-        }
-
-    }
-
-    private void loadRegistriesFromBackwardConfig() {
-        // for backward compatibility
-        // -Ddubbo.registry.address is now deprecated.
-        if (registries == null || registries.isEmpty()) {
-            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);
-                }
-            }
-        }
-    }
-
-    /**
-     * For compatibility purpose, use registry as the default config center if 
the registry protocol is zookeeper and
-     * there's no config center specified explicitly.
-     */
-    private void useRegistryForConfigIfNecessary() {
-        
registries.stream().filter(RegistryConfig::isZookeeperProtocol).findFirst().ifPresent(rc
 -> {
-            // we use the loading status of DynamicConfiguration to decide 
whether ConfigCenter has been initiated.
-            Environment.getInstance().getDynamicConfiguration().orElseGet(() 
-> {
-                ConfigCenterConfig configCenterConfig = new 
ConfigCenterConfig();
-                configCenterConfig.setProtocol(rc.getProtocol());
-                configCenterConfig.setAddress(rc.getAddress());
-                configCenterConfig.setHighestPriority(false);
-                configCenterConfig.init();
-                return null;
-            });
-        });
-    }
-
-    /**
-     * @return local
-     * @deprecated Replace to <code>getStub()</code>
-     */
-    @Deprecated
-    public String getLocal() {
-        return local;
-    }
-
-    /**
-     * @param local
-     * @deprecated Replace to <code>setStub(Boolean)</code>
-     */
-    @Deprecated
-    public void setLocal(Boolean local) {
-        if (local == null) {
-            setLocal((String) null);
-        } else {
-            setLocal(String.valueOf(local));
-        }
-    }
-
-    /**
-     * @param local
-     * @deprecated Replace to <code>setStub(String)</code>
-     */
-    @Deprecated
-    public void setLocal(String local) {
-        checkName("local", local);
-        this.local = local;
-    }
-
-    public String getStub() {
-        return stub;
-    }
-
-    public void setStub(Boolean stub) {
-        if (stub == null) {
-            setStub((String) null);
-        } else {
-            setStub(String.valueOf(stub));
-        }
-    }
-
-    public void setStub(String stub) {
-        checkName("stub", stub);
-        this.stub = stub;
-    }
-
-    public String getCluster() {
-        return cluster;
-    }
-
-    public void setCluster(String cluster) {
-        checkExtension(Cluster.class, "cluster", cluster);
-        this.cluster = cluster;
-    }
-
-    public String getProxy() {
-        return proxy;
-    }
-
-    public void setProxy(String proxy) {
-        checkExtension(ProxyFactory.class, "proxy", proxy);
-        this.proxy = proxy;
-    }
-
-    public Integer getConnections() {
-        return connections;
-    }
-
-    public void setConnections(Integer connections) {
-        this.connections = connections;
-    }
-
-    @Parameter(key = Constants.REFERENCE_FILTER_KEY, append = true)
-    public String getFilter() {
-        return filter;
-    }
-
-    public void setFilter(String filter) {
-        checkMultiExtension(Filter.class, "filter", filter);
-        this.filter = filter;
-    }
-
-    @Parameter(key = Constants.INVOKER_LISTENER_KEY, append = true)
-    public String getListener() {
-        return listener;
-    }
-
-    public void setListener(String listener) {
-        checkMultiExtension(InvokerListener.class, "listener", listener);
-        this.listener = listener;
-    }
-
-    public String getLayer() {
-        return layer;
-    }
-
-    public void setLayer(String layer) {
-        checkNameHasSymbol("layer", layer);
-        this.layer = layer;
-    }
-
-    public ApplicationConfig getApplication() {
-        return application;
-    }
-
-    public void setApplication(ApplicationConfig application) {
-        this.application = application;
-    }
-
-    public ModuleConfig getModule() {
-        return module;
-    }
-
-    public void setModule(ModuleConfig module) {
-        this.module = module;
-    }
-
-    public RegistryConfig getRegistry() {
-        return registries == null || registries.isEmpty() ? null : 
registries.get(0);
-    }
-
-    public void setRegistry(RegistryConfig registry) {
-        List<RegistryConfig> registries = new ArrayList<RegistryConfig>(1);
-        registries.add(registry);
-        this.registries = registries;
-    }
-
-    public List<RegistryConfig> getRegistries() {
-        return registries;
-    }
-
-    @SuppressWarnings({"unchecked"})
-    public void setRegistries(List<? extends RegistryConfig> registries) {
-        this.registries = (List<RegistryConfig>) registries;
-    }
-
-    @Parameter(excluded = true)
-    public String getRegistryIds() {
-        return registryIds;
-    }
-
-    public void setRegistryIds(String registryIds) {
-        this.registryIds = registryIds;
-    }
-
-    public MonitorConfig getMonitor() {
-        return monitor;
-    }
-
-    public void setMonitor(String monitor) {
-        this.monitor = new MonitorConfig(monitor);
-    }
-
-    public void setMonitor(MonitorConfig monitor) {
-        this.monitor = monitor;
-    }
-
-    public String getOwner() {
-        return owner;
-    }
-
-    public void setOwner(String owner) {
-        checkMultiName("owner", owner);
-        this.owner = owner;
-    }
-
-    public RegistryDataConfig getRegistryDataConfig() {
-        return registryDataConfig;
-    }
-
-    public void setRegistryDataConfig(RegistryDataConfig registryDataConfig) {
-        this.registryDataConfig = registryDataConfig;
-    }
-
-    public Integer getCallbacks() {
-        return callbacks;
-    }
-
-    public void setCallbacks(Integer callbacks) {
-        this.callbacks = callbacks;
-    }
-
-    public String getOnconnect() {
-        return onconnect;
-    }
-
-    public void setOnconnect(String onconnect) {
-        this.onconnect = onconnect;
-    }
-
-    public String getOndisconnect() {
-        return ondisconnect;
-    }
-
-    public void setOndisconnect(String ondisconnect) {
-        this.ondisconnect = ondisconnect;
-    }
-
-    public String getScope() {
-        return scope;
-    }
-
-    public void setScope(String scope) {
-        this.scope = scope;
-    }
-
-    public MetadataReportConfig getMetadataReportConfig() {
-        return metadataReportConfig;
-    }
-
-    public void setMetadataReportConfig(MetadataReportConfig 
metadataReportConfig) {
-        this.metadataReportConfig = metadataReportConfig;
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.config;
+
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.Version;
+import org.apache.dubbo.common.config.Environment;
+import org.apache.dubbo.common.utils.Assert;
+import org.apache.dubbo.common.utils.ConfigUtils;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.common.utils.ReflectUtils;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.common.utils.UrlUtils;
+import org.apache.dubbo.config.support.Parameter;
+import org.apache.dubbo.metadata.integration.MetadataReportService;
+import org.apache.dubbo.monitor.MonitorFactory;
+import org.apache.dubbo.monitor.MonitorService;
+import org.apache.dubbo.registry.RegistryService;
+import org.apache.dubbo.rpc.Filter;
+import org.apache.dubbo.rpc.InvokerListener;
+import org.apache.dubbo.rpc.ProxyFactory;
+import org.apache.dubbo.rpc.cluster.Cluster;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.support.MockInvoker;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.dubbo.common.Constants.APPLICATION_KEY;
+import static 
org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
+
+/**
+ * AbstractDefaultConfig
+ *
+ * @export
+ */
+public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
+
+    private static final long serialVersionUID = -1559314110797223229L;
+
+    /**
+     * Local impl class name for the service interface
+     */
+    protected String local;
+
+    /**
+     * Local stub class name for the service interface
+     */
+    protected String stub;
+
+    /**
+     * Service monitor
+     */
+    protected MonitorConfig monitor;
+
+    /**
+     * Strategies for generating dynamic agents,there are two strategies can 
be choosed: jdk and javassist
+     */
+    protected String proxy;
+
+    /**
+     * Cluster type
+     */
+    protected String cluster;
+
+    /**
+     * The {@link Filter} when the provicer side exposed a service or the 
customer side references a remote service used,
+     * if there are more than one, you can use commas to separate them
+     */
+    protected String filter;
+
+    /**
+     * The Listener when the provider side exposes a service or the customer 
side references a remote service used
+     * if there are more than one, you can use commas to separate them
+     */
+    protected String listener;
+
+    /**
+     * The owner of zhe service providers
+     */
+    protected String owner;
+
+    /**
+     * Connection limits, 0 means shared connection, otherwise it defines the 
connections delegated to the current service
+     */
+    protected Integer connections;
+
+    /**
+     * The layer of service providers
+     */
+    protected String layer;
+
+    /**
+     * The application info
+     */
+    protected ApplicationConfig application;
+
+    /**
+     * The module info
+     */
+    protected ModuleConfig module;
+
+    /**
+     * Registry centers
+     */
+    protected List<RegistryConfig> registries;
+
+    protected String registryIds;
+
+    // connection events
+    protected String onconnect;
+
+    /**
+     * Disconnection events
+     */
+    protected String ondisconnect;
+    protected MetadataReportConfig metadataReportConfig;
+    protected RegistryDataConfig registryDataConfig;
+    // callback limits
+    private Integer callbacks;
+    // the scope for referring/exporting a service, if it's local, it means 
searching in current JVM only.
+    private String scope;
+
+    /**
+     * Check whether the registry config is exists, and then conversion it to 
{@link RegistryConfig}
+     */
+    protected void checkRegistry() {
+        loadRegistriesFromBackwardConfig();
+
+        convertRegistryIdsToRegistries();
+
+        for (RegistryConfig registryConfig : registries) {
+            registryConfig.refresh();
+            if (StringUtils.isNotEmpty(registryConfig.getId())) {
+                registryConfig.setPrefix(Constants.REGISTRIES_SUFFIX);
+                registryConfig.refresh();
+            }
+        }
+
+        for (RegistryConfig registryConfig : registries) {
+            if (!registryConfig.isValid()) {
+                throw new IllegalStateException("No registry config found or 
it's not a valid config! " +
+                        "The registry config is: " + registryConfig);
+            }
+        }
+
+        useRegistryForConfigIfNecessary();
+    }
+
+    @SuppressWarnings("deprecation")
+    protected void checkApplication() {
+        // for backward compatibility
+        if (application == null) {
+            application = new ApplicationConfig();
+        }
+
+        application.refresh();
+
+        if (!application.isValid()) {
+            throw new IllegalStateException("No application config found or 
it's not a valid config! " +
+                    "Please add <dubbo:application name=\"...\" /> to your 
spring config.");
+        }
+
+        ApplicationModel.setApplication(application.getName());
+
+        // backward compatibility
+        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());
+            }
+        }
+    }
+
+    protected void checkMonitor() {
+        if (monitor == null) {
+            monitor = new MonitorConfig();
+        }
+
+        monitor.refresh();
+
+        if (!monitor.isValid()) {
+            logger.info("There's no valid monitor config found, if you want to 
open monitor statistics for Dubbo, " +
+                    "please make sure your monitor is configured properly.");
+        }
+    }
+
+    protected void checkMetadataReport() {
+        if (metadataReportConfig == null) {
+            metadataReportConfig = new MetadataReportConfig();
+        }
+        metadataReportConfig.refresh();
+        if (!metadataReportConfig.isValid()) {
+            logger.warn("There's no valid metadata config found, if you are 
using the simplified mode of registry url, " +
+                    "please make sure you have a metadata address configured 
properly.");
+        }
+    }
+
+    protected void checkRegistryDataConfig() {
+        if (registryDataConfig == null) {
+            registryDataConfig = new RegistryDataConfig();
+        }
+        registryDataConfig.refresh();
+        if (!registryDataConfig.isValid()) {
+            logger.info("There's no valid registryData config found. So the 
registry will store full url parameter " +
+                    "to registry server.");
+        }
+    }
+
+    /**
+     *
+     * Load the registry and conversion it to {@link URL}, the priority order 
is: system property > dubbo registry config
+     *
+     * @param provider whether it is the provider side
+     * @return
+     */
+    protected List<URL> loadRegistries(boolean provider) {
+        // check && override if necessary
+        checkRegistry();
+        checkRegistryDataConfig();
+        List<URL> registryList = new ArrayList<URL>();
+        if (registries != null && !registries.isEmpty()) {
+            Map<String, String> registryDataConfigurationMap = new 
HashMap<>(4);
+            appendParameters(registryDataConfigurationMap, registryDataConfig);
+            for (RegistryConfig config : registries) {
+                String address = config.getAddress();
+                if (StringUtils.isEmpty(address)) {
+                    address = Constants.ANYHOST_VALUE;
+                }
+                if (!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());
+                    appendRuntimeParameters(map);
+                    if (!map.containsKey("protocol")) {
+                        map.put("protocol", "dubbo");
+                    }
+                    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);
+                        // add parameter
+                        url = 
url.addParametersIfAbsent(registryDataConfigurationMap);
+                        if ((provider && 
url.getParameter(Constants.REGISTER_KEY, true))
+                                || (!provider && 
url.getParameter(Constants.SUBSCRIBE_KEY, true))) {
+                            registryList.add(url);
+                        }
+                    }
+                }
+            }
+        }
+        return registryList;
+    }
+
+    /**
+     *
+     * Load the monitor config from the system properties and conversation it 
to {@link URL}
+     *
+     * @param registryURL
+     * @return
+     */
+    protected URL loadMonitor(URL registryURL) {
+        checkMonitor();
+        Map<String, String> map = new HashMap<String, String>();
+        map.put(Constants.INTERFACE_KEY, MonitorService.class.getName());
+        appendRuntimeParameters(map);
+        //set ip
+        String hostToRegistry = 
ConfigUtils.getSystemProperty(Constants.DUBBO_IP_TO_REGISTRY);
+        if (hostToRegistry == null || hostToRegistry.length() == 0) {
+            hostToRegistry = NetUtils.getLocalHost();
+        } else if (NetUtils.isInvalidLocalHost(hostToRegistry)) {
+            throw new IllegalArgumentException("Specified invalid registry ip 
from property:" +
+                    Constants.DUBBO_IP_TO_REGISTRY + ", value:" + 
hostToRegistry);
+        }
+        map.put(Constants.REGISTER_IP_KEY, hostToRegistry);
+        appendParameters(map, monitor);
+        appendParameters(map, application);
+        String address = monitor.getAddress();
+        String sysaddress = System.getProperty("dubbo.monitor.address");
+        if (sysaddress != null && sysaddress.length() > 0) {
+            address = sysaddress;
+        }
+        if (ConfigUtils.isNotEmpty(address)) {
+            if (!map.containsKey(Constants.PROTOCOL_KEY)) {
+                if 
(getExtensionLoader(MonitorFactory.class).hasExtension("logstat")) {
+                    map.put(Constants.PROTOCOL_KEY, "logstat");
+                } else {
+                    map.put(Constants.PROTOCOL_KEY, Constants.DOBBO_PROTOCOL);
+                }
+            }
+            return UrlUtils.parseURL(address, map);
+        } else if (Constants.REGISTRY_PROTOCOL.equals(monitor.getProtocol()) 
&& registryURL != null) {
+          return 
registryURL.setProtocol(Constants.DOBBO_PROTOCOL).addParameter(Constants.PROTOCOL_KEY,
 Constants.REGISTRY_PROTOCOL).addParameterAndEncoded(Constants.REFER_KEY, 
StringUtils.toQueryString(map));
+        }
+        return null;
+    }
+
+    static void appendRuntimeParameters(Map<String, String> map) {
+        map.put(Constants.DUBBO_VERSION_KEY, Version.getProtocolVersion());
+        map.put(Constants.SPECIFICATION_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()));
+        }
+    }
+
+    private URL loadMetadataReporterURL(boolean provider) {
+        this.checkApplication();
+        String address = metadataReportConfig.getAddress();
+        if (address == null || address.length() == 0) {
+            return null;
+        }
+        Map<String, String> map = new HashMap<String, String>();
+        map.put(APPLICATION_KEY, application.getName());
+        appendParameters(map, metadataReportConfig);
+        return UrlUtils.parseURL(address, map);
+    }
+
+    protected MetadataReportService getMetadataReportService() {
+
+        if (metadataReportConfig == null || !metadataReportConfig.isValid()) {
+            return null;
+        }
+        return MetadataReportService.instance(() -> {
+            return loadMetadataReporterURL(true);
+        });
+    }
+
+    /**
+     * Check whether the remote service interface and the methods meet with 
Dubbo's requirements.it mainly check, if the
+     * methods configured in the configuration file are included in the 
interface of remote service
+     *
+     * @param interfaceClass the interface of remote service
+     * @param methods the methods configured
+     */
+    protected void checkInterfaceAndMethods(Class<?> interfaceClass, 
List<MethodConfig> methods) {
+        // interface cannot be null
+        Assert.notNull(interfaceClass, new IllegalStateException("interface 
not allow null!"));
+
+        // to verify interfaceClass is an interface
+        if (!interfaceClass.isInterface()) {
+            throw new IllegalStateException("The interface class " + 
interfaceClass + " is not a interface!");
+        }
+        // check if methods exist in the remote service interface
+        if (methods != null && !methods.isEmpty()) {
+            for (MethodConfig methodBean : methods) {
+                methodBean.setService(interfaceClass.getName());
+                methodBean.setServiceId(this.getId());
+                methodBean.refresh();
+                String methodName = methodBean.getName();
+                if (methodName == null || methodName.length() == 0) {
+                    throw new IllegalStateException("<dubbo:method> name 
attribute is required! Please check: " +
+                            "<dubbo:service interface=\"" + 
interfaceClass.getName() + "\" ... >" +
+                            "<dubbo:method name=\"\" ... 
/></<dubbo:reference>");
+                }
+
+                boolean hasMethod = 
Arrays.stream(interfaceClass.getMethods()).anyMatch(method -> 
method.getName().equals(methodName));
+                if (!hasMethod) {
+                    throw new IllegalStateException("The interface " + 
interfaceClass.getName()
+                            + " not found method " + methodName);
+                }
+            }
+        }
+    }
+
+    /**
+     * Legitimacy check and setup of local simulated operations. The 
operations can be a string with Simple operation or
+     * a classname whose {@link Class} implements a particular function
+     *
+     * @param interfaceClass for provider side, it is the {@link Class} of the 
service that will be exported; for consumer
+     *                       side, it is the {@link Class} of the remote 
service interface that will be referenced
+     */
+    void checkMock(Class<?> interfaceClass) {
+        if (ConfigUtils.isEmpty(mock)) {
+            return;
+        }
+
+        String normalizedMock = MockInvoker.normalizeMock(mock);
+        if (normalizedMock.startsWith(Constants.RETURN_PREFIX)) {
+            normalizedMock = 
normalizedMock.substring(Constants.RETURN_PREFIX.length()).trim();
+            try {
+                //Check whether the mock value is legal, if it is illegal, 
throw exception
+                MockInvoker.parseMockValue(normalizedMock);
+            } catch (Exception e) {
+                throw new IllegalStateException("Illegal mock return in 
<dubbo:service/reference ... " +
+                        "mock=\"" + mock + "\" />");
+            }
+        } else if (normalizedMock.startsWith(Constants.THROW_PREFIX)) {
+            normalizedMock = 
normalizedMock.substring(Constants.THROW_PREFIX.length()).trim();
+            if (ConfigUtils.isNotEmpty(normalizedMock)) {
+                try {
+                    //Check whether the mock value is legal
+                    MockInvoker.getThrowable(normalizedMock);
+                } catch (Exception e) {
+                    throw new IllegalStateException("Illegal mock throw in 
<dubbo:service/reference ... " +
+                            "mock=\"" + mock + "\" />");
+                }
+            }
+        } else {
+            //Check whether the mock class is a implementation of the 
interfaceClass, and if it has a default constructor
+            MockInvoker.getMockObject(normalizedMock, interfaceClass);
+        }
+    }
+
+    /**
+     * Legitimacy check of stub, note that: the local will deprecated, and 
replace with <code>stub</code>
+     *
+     * @param interfaceClass for provider side, it is the {@link Class} of the 
service that will be exported; for consumer
+     *                       side, it is the {@link Class} of the remote 
service interface
+     */
+    void checkStubAndLocal(Class<?> interfaceClass) {
+        if (ConfigUtils.isNotEmpty(local)) {
+            Class<?> localClass = ConfigUtils.isDefault(local) ?
+                    ReflectUtils.forName(interfaceClass.getName() + "Local") : 
ReflectUtils.forName(local);
+            verify(interfaceClass, localClass);
+        }
+        if (ConfigUtils.isNotEmpty(stub)) {
+            Class<?> localClass = ConfigUtils.isDefault(stub) ?
+                    ReflectUtils.forName(interfaceClass.getName() + "Stub") : 
ReflectUtils.forName(stub);
+            verify(interfaceClass, localClass);
+        }
+    }
+
+    private void verify(Class<?> interfaceClass, Class<?> localClass) {
+        if (!interfaceClass.isAssignableFrom(localClass)) {
+            throw new IllegalStateException("The local implementation class " 
+ localClass.getName() +
+                    " not implement interface " + interfaceClass.getName());
+        }
+
+        try {
+            //Check if the localClass a contructor with parameter who's type 
is interfaceClass
+            ReflectUtils.findConstructor(localClass, interfaceClass);
+        } catch (NoSuchMethodException e) {
+            throw new IllegalStateException("No such constructor \"public " + 
localClass.getSimpleName() +
+                    "(" + interfaceClass.getName() + ")\" in local 
implementation class " + localClass.getName());
+        }
+    }
+
+    private void overrideParameters(Map<String, String> map) {
+        map.put(Constants.PATH_KEY, RegistryService.class.getName());
+        map.put(Constants.DOBBO_PROTOCOL, Version.getProtocolVersion());
+        map.put(Constants.TIMESTAMP_KEY, 
String.valueOf(System.currentTimeMillis()));
+        if (ConfigUtils.getPid() > 0) {
+            map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));
+        }
+        map.putIfAbsent(Constants.PROTOCOL_KEY, Constants.DOBBO_PROTOCOL);
+    }
+
+    private void convertRegistryIdsToRegistries() {
+        if (StringUtils.isEmpty(registryIds) && (registries == null || 
registries.isEmpty())) {
+            Set<String> configedRegistries = new HashSet<>();
+            
configedRegistries.addAll(getSubProperties(Environment.getInstance().getExternalConfigurationMap(),
+                    Constants.REGISTRIES_SUFFIX));
+            
configedRegistries.addAll(getSubProperties(Environment.getInstance().getAppExternalConfigurationMap(),
+                    Constants.REGISTRIES_SUFFIX));
+
+            registryIds = String.join(",", configedRegistries);
+        }
+
+        if (StringUtils.isEmpty(registryIds)) {
+            if (registries == null || registries.isEmpty()) {
+                registries = new ArrayList<>();
+                registries.add(new RegistryConfig());
+            }
+        } else {
+            String[] arr = Constants.COMMA_SPLIT_PATTERN.split(registryIds);
+            if (registries == null || registries.isEmpty()) {
+                registries = new ArrayList<>();
+            }
+            Arrays.stream(arr).forEach(id -> {
+                if (registries.stream().noneMatch(reg -> 
reg.getId().equals(id))) {
+                    RegistryConfig registryConfig = new RegistryConfig();
+                    registryConfig.setId(id);
+                    registries.add(registryConfig);
+                }
+            });
+            if (registries.size() > arr.length) {
+                throw new IllegalStateException("Too much registries found, 
the registries assigned to this service " +
+                        "are :" + registryIds + ", but got " + 
registries.size() + " registries!");
+            }
+        }
+
+    }
+
+    private void loadRegistriesFromBackwardConfig() {
+        // for backward compatibility
+        // -Ddubbo.registry.address is now deprecated.
+        if (registries == null || registries.isEmpty()) {
+            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);
+                }
+            }
+        }
+    }
+
+    /**
+     * For compatibility purpose, use registry as the default config center if 
the registry protocol is zookeeper and
+     * there's no config center specified explicitly.
+     */
+    private void useRegistryForConfigIfNecessary() {
+        
registries.stream().filter(RegistryConfig::isZookeeperProtocol).findFirst().ifPresent(rc
 -> {
+            // we use the loading status of DynamicConfiguration to decide 
whether ConfigCenter has been initiated.
+            Environment.getInstance().getDynamicConfiguration().orElseGet(() 
-> {
+                ConfigCenterConfig configCenterConfig = new 
ConfigCenterConfig();
+                configCenterConfig.setProtocol(rc.getProtocol());
+                configCenterConfig.setAddress(rc.getAddress());
+                configCenterConfig.setHighestPriority(false);
+                configCenterConfig.init();
+                return null;
+            });
+        });
+    }
+
+    /**
+     * @return local
+     * @deprecated Replace to <code>getStub()</code>
+     */
+    @Deprecated
+    public String getLocal() {
+        return local;
+    }
+
+    /**
+     * @param local
+     * @deprecated Replace to <code>setStub(Boolean)</code>
+     */
+    @Deprecated
+    public void setLocal(Boolean local) {
+        if (local == null) {
+            setLocal((String) null);
+        } else {
+            setLocal(String.valueOf(local));
+        }
+    }
+
+    /**
+     * @param local
+     * @deprecated Replace to <code>setStub(String)</code>
+     */
+    @Deprecated
+    public void setLocal(String local) {
+        checkName("local", local);
+        this.local = local;
+    }
+
+    public String getStub() {
+        return stub;
+    }
+
+    public void setStub(Boolean stub) {
+        if (stub == null) {
+            setStub((String) null);
+        } else {
+            setStub(String.valueOf(stub));
+        }
+    }
+
+    public void setStub(String stub) {
+        checkName("stub", stub);
+        this.stub = stub;
+    }
+
+    public String getCluster() {
+        return cluster;
+    }
+
+    public void setCluster(String cluster) {
+        checkExtension(Cluster.class, "cluster", cluster);
+        this.cluster = cluster;
+    }
+
+    public String getProxy() {
+        return proxy;
+    }
+
+    public void setProxy(String proxy) {
+        checkExtension(ProxyFactory.class, "proxy", proxy);
+        this.proxy = proxy;
+    }
+
+    public Integer getConnections() {
+        return connections;
+    }
+
+    public void setConnections(Integer connections) {
+        this.connections = connections;
+    }
+
+    @Parameter(key = Constants.REFERENCE_FILTER_KEY, append = true)
+    public String getFilter() {
+        return filter;
+    }
+
+    public void setFilter(String filter) {
+        checkMultiExtension(Filter.class, "filter", filter);
+        this.filter = filter;
+    }
+
+    @Parameter(key = Constants.INVOKER_LISTENER_KEY, append = true)
+    public String getListener() {
+        return listener;
+    }
+
+    public void setListener(String listener) {
+        checkMultiExtension(InvokerListener.class, "listener", listener);
+        this.listener = listener;
+    }
+
+    public String getLayer() {
+        return layer;
+    }
+
+    public void setLayer(String layer) {
+        checkNameHasSymbol("layer", layer);
+        this.layer = layer;
+    }
+
+    public ApplicationConfig getApplication() {
+        return application;
+    }
+
+    public void setApplication(ApplicationConfig application) {
+        this.application = application;
+    }
+
+    public ModuleConfig getModule() {
+        return module;
+    }
+
+    public void setModule(ModuleConfig module) {
+        this.module = module;
+    }
+
+    public RegistryConfig getRegistry() {
+        return registries == null || registries.isEmpty() ? null : 
registries.get(0);
+    }
+
+    public void setRegistry(RegistryConfig registry) {
+        List<RegistryConfig> registries = new ArrayList<RegistryConfig>(1);
+        registries.add(registry);
+        this.registries = registries;
+    }
+
+    public List<RegistryConfig> getRegistries() {
+        return registries;
+    }
+
+    @SuppressWarnings({"unchecked"})
+    public void setRegistries(List<? extends RegistryConfig> registries) {
+        this.registries = (List<RegistryConfig>) registries;
+    }
+
+    @Parameter(excluded = true)
+    public String getRegistryIds() {
+        return registryIds;
+    }
+
+    public void setRegistryIds(String registryIds) {
+        this.registryIds = registryIds;
+    }
+
+    public MonitorConfig getMonitor() {
+        return monitor;
+    }
+
+    public void setMonitor(String monitor) {
+        this.monitor = new MonitorConfig(monitor);
+    }
+
+    public void setMonitor(MonitorConfig monitor) {
+        this.monitor = monitor;
+    }
+
+    public String getOwner() {
+        return owner;
+    }
+
+    public void setOwner(String owner) {
+        checkMultiName("owner", owner);
+        this.owner = owner;
+    }
+
+    public RegistryDataConfig getRegistryDataConfig() {
+        return registryDataConfig;
+    }
+
+    public void setRegistryDataConfig(RegistryDataConfig registryDataConfig) {
+        this.registryDataConfig = registryDataConfig;
+    }
+
+    public Integer getCallbacks() {
+        return callbacks;
+    }
+
+    public void setCallbacks(Integer callbacks) {
+        this.callbacks = callbacks;
+    }
+
+    public String getOnconnect() {
+        return onconnect;
+    }
+
+    public void setOnconnect(String onconnect) {
+        this.onconnect = onconnect;
+    }
+
+    public String getOndisconnect() {
+        return ondisconnect;
+    }
+
+    public void setOndisconnect(String ondisconnect) {
+        this.ondisconnect = ondisconnect;
+    }
+
+    public String getScope() {
+        return scope;
+    }
+
+    public void setScope(String scope) {
+        this.scope = scope;
+    }
+
+    public MetadataReportConfig getMetadataReportConfig() {
+        return metadataReportConfig;
+    }
+
+    public void setMetadataReportConfig(MetadataReportConfig 
metadataReportConfig) {
+        this.metadataReportConfig = metadataReportConfig;
+    }
+
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractMethodConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractMethodConfig.java
index 746ac6b..0248b9a 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractMethodConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractMethodConfig.java
@@ -31,41 +31,69 @@ public abstract class AbstractMethodConfig extends 
AbstractConfig {
 
     private static final long serialVersionUID = 1L;
 
-    // timeout for remote invocation in milliseconds
+    /**
+     * The timeout for remote invocation in milliseconds
+     */
     protected Integer timeout;
 
-    // retry times
+    /**
+     * The retry times
+     */
     protected Integer retries;
 
-    // max concurrent invocations
+    /**
+     * max concurrent invocations
+     */
     protected Integer actives;
 
-    // load balance
+    /**
+     * The load balance
+     */
     protected String loadbalance;
 
-    // whether to async
+    /**
+     * Whether to async
+     * note that: it is an unreliable asynchronism that ignores return values 
and does not block threads.
+     */
     protected Boolean async;
 
-    // whether to ack async-sent
+    /**
+     * Whether to ack async-sent
+     */
     protected Boolean sent;
 
-    // the name of mock class which gets called when a service fails to execute
+    /**
+     * The name of mock class which gets called when a service fails to execute
+     *
+     * note that: the mock doesn't support on the provider side,and the mock 
is executed when a non-business exception
+     * occurs after a remote service call
+     */
     protected String mock;
 
-    // merger
+    /**
+     * Merger
+     */
     protected String merger;
 
-    // cache
+    /**
+     * Cache the return result with the call parameter as key, the following 
options are available: lru, threadlocal,
+     * jcache, etc.
+     */
     protected String cache;
 
-    // validation
+    /**
+     * Whether JSR303 standard annotation validation is enabled or not, if 
enabled, annotations on method parameters will
+     * be validated
+     */
     protected String validation;
 
-    // customized parameters
+    /**
+     * The customized parameters
+     */
     protected Map<String, String> parameters;
 
     /**
-     * forks for forking cluster
+     * Forks for forking cluster
      */
     protected Integer forks;
 
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractReferenceConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractReferenceConfig.java
index 12af7ca..325b1f1 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractReferenceConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractReferenceConfig.java
@@ -33,32 +33,49 @@ public abstract class AbstractReferenceConfig extends 
AbstractInterfaceConfig {
 
     // ======== Reference config default values, will take effect if 
reference's attribute is not set  ========
 
-    // check if service provider exists
+    /**
+     * Check if service provider exists, if not exists, it will be fast fail
+     */
     protected Boolean check;
 
-    // whether to eagle-init
+    /**
+     * Whether to eagle-init
+     */
     protected Boolean init;
 
-    // whether to use generic interface
+    /**
+     * Whether to use generic interface
+     */
     protected String generic;
 
-    // whether to find reference's instance from the current JVM
+    /**
+     * Whether to find reference's instance from the current JVM
+     */
     protected Boolean injvm;
 
-    // lazy create connection
+    /**
+     * Lazy create connection
+     */
     protected Boolean lazy;
 
     protected String reconnect;
 
     protected Boolean sticky;
 
-    // whether to support event in stub. //TODO solve merge problem
+    /**
+     * Whether to support event in stub.
+     */
+    //TODO solve merge problem
     protected Boolean stubevent;//= Constants.DEFAULT_STUB_EVENT;
 
-    // version
+    /**
+     * The remote service version the customer side will reference
+     */
     protected String version;
 
-    // group
+    /**
+     * The remote service group the customer side will reference
+     */
     protected String group;
 
     public Boolean isCheck() {
@@ -98,7 +115,7 @@ public abstract class AbstractReferenceConfig extends 
AbstractInterfaceConfig {
 
     /**
      * @return
-     * @deprecated instead, use scope to judge if it's in jvm, scope=local
+     * @deprecated instead, use the parameter <b>scope</> to judge if it's in 
jvm, scope=local
      */
     @Deprecated
     public Boolean isInjvm() {
@@ -107,7 +124,7 @@ public abstract class AbstractReferenceConfig extends 
AbstractInterfaceConfig {
 
     /**
      * @param injvm
-     * @deprecated instead, use scope to judge if it's in jvm, scope=local
+     * @deprecated instead, use the parameter <b>scope</b> to judge if it's in 
jvm, scope=local
      */
     @Deprecated
     public void setInjvm(Boolean injvm) {
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java
index 191fcf8..ed8ba4a 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java
@@ -32,46 +32,81 @@ public abstract class AbstractServiceConfig extends 
AbstractInterfaceConfig {
 
     private static final long serialVersionUID = 1L;
 
-    // version
+    /**
+     * The service version
+     */
     protected String version;
 
-    // group
+    /**
+     * The service group
+     */
     protected String group;
 
-    // whether the service is deprecated
+    /**
+     * whether the service is deprecated
+     */
     protected Boolean deprecated;
 
-    // delay service exporting
+    /**
+     * The time delay register service (milliseconds)
+     */
     protected Integer delay;
 
-    // whether to export the service
+    /**
+     * Whether to export the service
+     */
     protected Boolean export;
 
-    // weight
+    /**
+     * The service weight
+     */
     protected Integer weight;
 
-    // document center
+    /**
+     * Document center
+     */
     protected String document;
 
-    // whether to register as a dynamic service or not on register center
+    /**
+     * Whether to register as a dynamic service or not on register center, it 
the value is false, the status will be disabled
+     * after the service registered,and it needs to be enabled manually; if 
you want to disable the service, you also need
+     * manual processing
+     */
     protected Boolean dynamic;
 
-    // whether to use token
+    /**
+     * Whether to use token
+     */
     protected String token;
 
-    // access log
+    /**
+     * Whether to export access logs to logs
+     */
     protected String accesslog;
+
+    /**
+     * The protocol list the service will export with
+     */
     protected List<ProtocolConfig> protocols;
     protected String protocolIds;
     // provider tag
     protected String tag;
     // max allowed execute times
     private Integer executes;
-    // whether to register
+
+    /**
+     * Whether to register
+     */
     private Boolean register;
-    // warm up period
+
+    /**
+     * Warm up period
+     */
     private Integer warmup;
-    // serialization
+
+    /**
+     * The serialization type
+     */
     private String serialization;
 
     public String getVersion() {
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ApplicationConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ApplicationConfig.java
index 6b1f531..fa184c8 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ApplicationConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ApplicationConfig.java
@@ -28,7 +28,7 @@ import java.util.Map;
 
 
 /**
- * ApplicationConfig
+ * The application info
  *
  * @export
  */
@@ -36,56 +36,90 @@ public class ApplicationConfig extends AbstractConfig {
 
     private static final long serialVersionUID = 5508512956753757169L;
 
-    // application name
+    /**
+     * Application name
+     */
     private String name;
 
-    // module version
+    /**
+     * The application version
+     */
     private String version;
 
-    // application owner
+    /**
+     * Application owner
+     */
     private String owner;
 
-    // application's organization (BU)
+    /**
+     * Application's organization (BU)
+     */
     private String organization;
 
-    // architecture layer
+    /**
+     * Architecture layer
+     */
     private String architecture;
 
-    // environment, e.g. dev, test or production
+    /**
+     * Environment, e.g. dev, test or production
+     */
     private String environment;
 
-    // Java compiler
+    /**
+     * Java compiler
+     */
     private String compiler;
 
-    // logger
+    /**
+     * The type of the log access
+     */
     private String logger;
 
-    // registry centers
+    /**
+     * Registry centers
+     */
     private List<RegistryConfig> registries;
     private String registryIds;
 
-    // monitor center
+    /**
+     * Monitor center
+     */
     private MonitorConfig monitor;
 
-    // is default or not
+    /**
+     * Is default or not
+     */
     private Boolean isDefault;
 
-    // directory for saving thread dump
+    /**
+     * Directory for saving thread dump
+     */
     private String dumpDirectory;
 
-    // whether to enable qos or not
+    /**
+     * Whether to enable qos or not
+     */
     private Boolean qosEnable;
 
-    // the qos port to listen
+    /**
+     * The qos port to listen
+     */
     private Integer qosPort;
 
-    // should we accept foreign ip or not?
+    /**
+     * Should we accept foreign ip or not?
+     */
     private Boolean qosAcceptForeignIp;
 
-    // customized parameters
+    /**
+     * Customized parameters
+     */
     private Map<String, String> parameters;
 
-    //config the shutdown.wait
+    /**
+     * Config the shutdown.wait
+     */
     private String shutwait;
 
 
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ArgumentConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ArgumentConfig.java
index bdb80de..61db01f 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ArgumentConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ArgumentConfig.java
@@ -21,19 +21,27 @@ import org.apache.dubbo.config.support.Parameter;
 import java.io.Serializable;
 
 /**
+ * The method arguments configuration
+ *
  * @export
  */
 public class ArgumentConfig implements Serializable {
 
     private static final long serialVersionUID = -2165482463925213595L;
 
-    //argument: index -1 represents not set
+    /**
+     * The argument index: index -1 represents not set
+     */
     private Integer index = -1;
 
-    //argument type
+    /**
+     * Argument type
+     */
     private String type;
 
-    //callback interface
+    /**
+     * Whether the argument is the callback interface
+     */
     private Boolean callback;
 
     @Parameter(excluded = true)
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ConsumerConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ConsumerConfig.java
index 4b482e7..ce10655 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ConsumerConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ConsumerConfig.java
@@ -19,7 +19,7 @@ package org.apache.dubbo.config;
 import org.apache.dubbo.common.utils.StringUtils;
 
 /**
- * ConsumerConfig
+ * The service consumer default confuguration
  *
  * @export
  */
@@ -27,22 +27,34 @@ public class ConsumerConfig extends AbstractReferenceConfig 
{
 
     private static final long serialVersionUID = 2827274711143680600L;
 
-    // is default or not
+    /**
+     * Whether to use the default protocol
+     */
     private Boolean isDefault;
 
-    // networking framework client uses: netty, mina, etc.
+    /**
+     * Networking framework client uses: netty, mina, etc.
+     */
     private String client;
 
-    // consumer thread pool type: cached, fixed, limit, eager
+    /**
+     * Consumer thread pool type: cached, fixed, limit, eager
+     */
     private String threadpool;
 
-    // consumer threadpool core thread size
+    /**
+     * Consumer threadpool core thread size
+     */
     private Integer corethreads;
 
-    // consumer threadpool thread size
+    /**
+     * Consumer threadpool thread size
+     */
     private Integer threads;
 
-    // consumer threadpool queue size
+    /**
+     * Consumer threadpool queue size
+     */
     private Integer queues;
 
     @Override
@@ -106,4 +118,4 @@ public class ConsumerConfig extends AbstractReferenceConfig 
{
     public void setQueues(Integer queues) {
         this.queues = queues;
     }
-}
\ No newline at end of file
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MetadataReportConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MetadataReportConfig.java
index a0928b6..a134eef 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MetadataReportConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MetadataReportConfig.java
@@ -29,31 +29,31 @@ import java.util.Map;
 public class MetadataReportConfig extends AbstractConfig {
 
     private static final long serialVersionUID = 55233L;
-    // register center address
+    // Register center address
     private String address;
 
-    // username to login register center
+    // Username to login register center
     private String username;
 
-    // password to login register center
+    // Password to login register center
     private String password;
 
-    // request timeout in milliseconds for register center
+    // Request timeout in milliseconds for register center
     private Integer timeout;
 
-    // customized parameters
+    // Customized parameters
     private Map<String, String> parameters;
 
     private Integer retryTimes;
 
     private Integer retryPeriod;
     /**
-     * by default the metadatastore will store full metadata repeatly every 
day .
+     * By default the metadatastore will store full metadata repeatly every 
day .
      */
     private Boolean cycleReport;
 
     /**
-     * sync report, default async
+     * Sync report, default async
      */
     private Boolean syncReport;
 
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MethodConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MethodConfig.java
index 50ac47d..d65c665 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MethodConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MethodConfig.java
@@ -23,7 +23,7 @@ import org.apache.dubbo.config.support.Parameter;
 import java.util.List;
 
 /**
- * MethodConfig
+ * The method configuration
  *
  * @export
  */
@@ -31,48 +31,79 @@ public class MethodConfig extends AbstractMethodConfig {
 
     private static final long serialVersionUID = 884908855422675941L;
 
-    // method name
+    /**
+     * The method name
+     */
     private String name;
 
-    // stat
+    /**
+     * Stat
+     */
     private Integer stat;
 
-    // whether to retry
+    /**
+     * Whether to retry
+     */
     private Boolean retry;
 
-    // if it's reliable
+    /**
+     * If it's reliable
+     */
     private Boolean reliable;
 
-    // thread limits for method invocations
+    /**
+     * Thread limits for method invocations
+     */
     private Integer executes;
 
-    // if it's deprecated
+    /**
+     * If it's deprecated
+     */
     private Boolean deprecated;
 
-    // whether to enable sticky
+    /**
+     * Whether to enable sticky
+     */
     private Boolean sticky;
 
-    // whether need to return
+    /**
+     * Whether need to return
+     */
     private Boolean isReturn;
 
-    // callback instance when async-call is invoked
+    /**
+     * Callback instance when async-call is invoked
+     */
     private Object oninvoke;
 
-    // callback method when async-call is invoked
+    /**
+     * Callback method when async-call is invoked
+     */
     private String oninvokeMethod;
 
-    // callback instance when async-call is returned
+    /**
+     * Callback instance when async-call is returned
+     */
     private Object onreturn;
 
-    // callback method when async-call is returned
+    /**
+     * Callback method when async-call is returned
+     */
     private String onreturnMethod;
 
-    // callback instance when async-call has exception thrown
+    /**
+     * Callback instance when async-call has exception thrown
+     */
     private Object onthrow;
 
-    // callback method when async-call has exception thrown
+    /**
+     * Callback method when async-call has exception thrown
+     */
     private String onthrowMethod;
 
+    /**
+     * The method arguments
+     */
     private List<ArgumentConfig> arguments;
 
     /**
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ModuleConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ModuleConfig.java
index f07638f..3616809 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ModuleConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ModuleConfig.java
@@ -23,7 +23,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 /**
- * ModuleConfig
+ * The module info
  *
  * @export
  */
@@ -31,25 +31,39 @@ public class ModuleConfig extends AbstractConfig {
 
     private static final long serialVersionUID = 5508512956753757169L;
 
-    // module name
+    /**
+     * Module name
+     */
     private String name;
 
-    // module version
+    /**
+     * Module version
+     */
     private String version;
 
-    // module owner
+    /**
+     * Module owner
+     */
     private String owner;
 
-    // module's organization
+    /**
+     * Module's organization
+     */
     private String organization;
 
-    // registry centers
+    /**
+     * Registry centers
+     */
     private List<RegistryConfig> registries;
 
-    // monitor center
+    /**
+     * Monitor center
+     */
     private MonitorConfig monitor;
 
-    // if it's default
+    /**
+     * If it's default
+     */
     private Boolean isDefault;
 
     public ModuleConfig() {
@@ -138,4 +152,4 @@ public class ModuleConfig extends AbstractConfig {
         this.isDefault = isDefault;
     }
 
-}
\ No newline at end of file
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MonitorConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MonitorConfig.java
index 1ca1109..5058aa0 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MonitorConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MonitorConfig.java
@@ -30,12 +30,25 @@ public class MonitorConfig extends AbstractConfig {
 
     private static final long serialVersionUID = -1184681514659198203L;
 
+    /**
+     * The protocol of the monitor, if the value is registry, it will search 
the monitor address from the registry center,
+     * otherwise, it will directly connect to the monitor center
+     */
     private String protocol;
 
+    /**
+     * The monitor address
+     */
     private String address;
 
+    /**
+     * The monitor user name
+     */
     private String username;
 
+    /**
+     * The password
+     */
     private String password;
 
     private String group;
@@ -44,10 +57,14 @@ public class MonitorConfig extends AbstractConfig {
 
     private String interval;
 
-    // customized parameters
+    /**
+     * customized parameters
+     */
     private Map<String, String> parameters;
 
-    // if it's default
+    /**
+     * If it's default
+     */
     private Boolean isDefault;
 
     public MonitorConfig() {
@@ -140,4 +157,4 @@ public class MonitorConfig extends AbstractConfig {
         return StringUtils.isNotEmpty(address);
     }
 
-}
\ No newline at end of file
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ProtocolConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ProtocolConfig.java
index 1f6bc3c..f419244 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ProtocolConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ProtocolConfig.java
@@ -41,101 +41,163 @@ public class ProtocolConfig extends AbstractConfig {
 
     private static final long serialVersionUID = 6913423882496634749L;
 
-    // protocol name
+    /**
+     * Protocol name
+     */
     private String name;
 
-    // service IP address (when there are multiple network cards available)
+    /**
+     * Service ip address (when there are multiple network cards available)
+     */
     private String host;
 
-    // service port
+    /**
+     * Service port
+     */
     private Integer port;
 
-    // context path
+    /**
+     * Context path
+     */
     private String contextpath;
 
-    // thread pool
+    /**
+     * Thread pool
+     */
     private String threadpool;
 
-    // thread pool core thread size
+    /**
+     * Thread pool core thread size
+     */
     private Integer corethreads;
 
-    // thread pool size (fixed size)
+    /**
+     * Thread pool size (fixed size)
+     */
     private Integer threads;
 
-    // IO thread pool size (fixed size)
+    /**
+     * IO thread pool size (fixed size)
+     */
     private Integer iothreads;
 
-    // thread pool's queue length
+    /**
+     * Thread pool's queue length
+     */
     private Integer queues;
 
-    // max acceptable connections
+    /**
+     * Max acceptable connections
+     */
     private Integer accepts;
 
-    // protocol codec
+    /**
+     * Protocol codec
+     */
     private String codec;
 
-    // serialization
+    /**
+     * Serialization
+     */
     private String serialization;
 
-    // charset
+    /**
+     * Charset
+     */
     private String charset;
 
-    // payload max length
+    /**
+     * Payload max length
+     */
     private Integer payload;
 
-    // buffer size
+    /**
+     * Buffer size
+     */
     private Integer buffer;
 
-    // heartbeat interval
+    /**
+     * Heartbeat interval
+     */
     private Integer heartbeat;
 
-    // access log
+    /**
+     * Access log
+     */
     private String accesslog;
 
-    // transfort
+    /**
+     * Transfort
+     */
     private String transporter;
 
-    // how information is exchanged
+    /**
+     * How information is exchanged
+     */
     private String exchanger;
 
-    // thread dispatch mode
+    /**
+     * Thread dispatch mode
+     */
     private String dispatcher;
 
-    // networker
+    /**
+     * Networker
+     */
     private String networker;
 
-    // sever impl
+    /**
+     * Sever impl
+     */
     private String server;
 
-    // client impl
+    /**
+     * Client impl
+     */
     private String client;
 
-    // supported telnet commands, separated with comma.
+    /**
+     * Supported telnet commands, separated with comma.
+     */
     private String telnet;
 
-    // command line prompt
+    /**
+     * Command line prompt
+     */
     private String prompt;
 
-    // status check
+    /**
+     * Status check
+     */
     private String status;
 
-    // whether to register
+    /**
+     * Whether to register
+     */
     private Boolean register;
 
-    // parameters
-    // 是否长连接
-    // TODO add this to provider config
+    /**
+     * whether it is a persistent connection
+     */
+    //TODO add this to provider config
     private Boolean keepAlive;
 
     // TODO add this to provider config
     private String optimizer;
 
+    /**
+     * The extension
+     */
     private String extension;
 
-    // parameters
+    /**
+     * The customized parameters
+     */
     private Map<String, String> parameters;
 
-    // if it's default
+    /**
+     * If it's default
+     */
     private Boolean isDefault;
 
     public ProtocolConfig() {
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ProviderConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ProviderConfig.java
index aeb4efa..ddfba1f 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ProviderConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ProviderConfig.java
@@ -28,7 +28,7 @@ import org.apache.dubbo.remoting.telnet.TelnetHandler;
 import java.util.Arrays;
 
 /**
- * ProviderConfig
+ * The service provider default configuration
  *
  * @export
  * @see org.apache.dubbo.config.ProtocolConfig
@@ -40,73 +40,119 @@ public class ProviderConfig extends AbstractServiceConfig {
 
     // ======== protocol default values, it'll take effect when protocol's 
attributes are not set ========
 
-    // service IP addresses (used when there are multiple network cards 
available)
+    /**
+     * Service ip addresses (used when there are multiple network cards 
available)
+     */
     private String host;
 
-    // service port
+    /**
+     * Service port
+     */
     private Integer port;
 
-    // context path
+    /**
+     * Context path
+     */
     private String contextpath;
 
-    // thread pool
+    /**
+     * Thread pool
+     */
     private String threadpool;
 
-    // thread pool size (fixed size)
+    /**
+     * Thread pool size (fixed size)
+     */
     private Integer threads;
 
-    // IO thread pool size (fixed size)
+    /**
+     * IO thread pool size (fixed size)
+     */
     private Integer iothreads;
 
-    // thread pool queue length
+    /**
+     * Thread pool queue length
+     */
     private Integer queues;
 
-    // max acceptable connections
+    /**
+     * Max acceptable connections
+     */
     private Integer accepts;
 
-    // protocol codec
+    /**
+     * Protocol codec
+     */
     private String codec;
 
-    // charset
+    /**
+     * The serialization charset
+     */
     private String charset;
 
-    // payload max length
+    /**
+     * Payload max length
+     */
     private Integer payload;
 
-    // buffer size
+    /**
+     * The network io buffer size
+     */
     private Integer buffer;
 
-    // transporter
+    /**
+     * Transporter
+     */
     private String transporter;
 
-    // how information gets exchanged
+    /**
+     * How information gets exchanged
+     */
     private String exchanger;
 
-    // thread dispatching mode
+    /**
+     * Thread dispatching mode
+     */
     private String dispatcher;
 
-    // networker
+    /**
+     * Networker
+     */
     private String networker;
 
-    // server impl
+    /**
+     * The server-side implementation model of the protocol
+     */
     private String server;
 
-    // client impl
+    /**
+     * The client-side implementation model of the protocol
+     */
     private String client;
 
-    // supported telnet commands, separated with comma.
+    /**
+     * Supported telnet commands, separated with comma.
+     */
     private String telnet;
 
-    // command line prompt
+    /**
+     * Command line prompt
+     */
     private String prompt;
 
-    // status check
+    /**
+     * Status check
+     */
     private String status;
 
-    // wait time when stop
+    /**
+     * Wait time when stop
+     */
     private Integer wait;
 
-    // if it's default
+    /**
+     * Whether to use the default protocol
+     */
     private Boolean isDefault;
 
     @Deprecated
@@ -380,4 +426,4 @@ public class ProviderConfig extends AbstractServiceConfig {
         this.wait = wait;
     }
 
-}
\ No newline at end of file
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
index 198f7c3..ea75c3d 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
@@ -62,29 +62,91 @@ public class ReferenceConfig<T> extends 
AbstractReferenceConfig {
 
     private static final long serialVersionUID = -5864351140409987595L;
 
+    /**
+     * The {@link Protocol} implementation with adaptive functionality,it will 
be different in different scenarios.
+     * A particular {@link Protocol} implementation is determined by the 
protocol attribute in the {@link URL}.
+     * For example:
+     *
+     * <li>when the url is 
registry://224.5.6.7:1234/org.apache.dubbo.registry.RegistryService?application=dubbo-sample,
+     * then the protocol is <b>RegistryProtocol</b></li>
+     *
+     * <li>when the url is 
dubbo://224.5.6.7:1234/org.apache.dubbo.config.api.DemoService?application=dubbo-sample,
 then
+     * the protocol is <b>DubboProtocol</b></li>
+     *
+     * Actually,when the {@link ExtensionLoader} init the {@link Protocol} 
instants,it will automatically wraps two
+     * layers, and eventually will get a <b>ProtocolFilterWrapper</b> or 
<b>ProtocolListenerWrapper</b>
+     */
     private static final Protocol refprotocol = 
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
 
+    /**
+     * The {@link Cluster}'s implementation with adaptive functionality, and 
actually it will get a {@link Cluster}'s
+     * specific implementation who is wrapped with <b>MockClusterInvoker</b>
+     */
     private static final Cluster cluster = 
ExtensionLoader.getExtensionLoader(Cluster.class).getAdaptiveExtension();
 
+    /**
+     * A {@link ProxyFactory} implementation that will generate a reference 
service's proxy,the JavassistProxyFactory is
+     * its default implementation
+     */
     private static final ProxyFactory proxyFactory = 
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+
+    /**
+     * The url of the reference service
+     */
     private final List<URL> urls = new ArrayList<URL>();
-    // interface name
+
+    /**
+     * The interface name of the reference service
+     */
     private String interfaceName;
+
+    /**
+     * The interface class of the reference service
+     */
     private Class<?> interfaceClass;
     // client type
     private String client;
-    // url for peer-to-peer invocation
+
+    /**
+     * The url for peer-to-peer invocation
+     */
     private String url;
-    // method configs
+
+    /**
+     * The method configs
+     */
     private List<MethodConfig> methods;
-    // default config
+
+    /**
+     * The consumer config (default)
+     */
     private ConsumerConfig consumer;
+
+    /**
+     * Only the service provider of the specified protocol is invoked, and 
other protocols are ignored.
+     */
     private String protocol;
-    // interface proxy reference
+
+    /**
+     * The interface proxy reference
+     */
     private transient volatile T ref;
+
+    /**
+     * The invoker of the reference service
+     */
     private transient volatile Invoker<?> invoker;
+
+    /**
+     * The flag whether the ReferenceConfig has been initialized
+     */
     private transient volatile boolean initialized;
+
+    /**
+     * whether this ReferenceConfig has been destroyed
+     */
     private transient volatile boolean destroyed;
+
     @SuppressWarnings("unused")
     private final Object finalizerGuardian = new Object() {
         @Override
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/RegistryConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/RegistryConfig.java
index 512fbe8..6abbdae 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/RegistryConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/RegistryConfig.java
@@ -31,22 +31,35 @@ public class RegistryConfig extends AbstractConfig {
 
     public static final String NO_AVAILABLE = "N/A";
     private static final long serialVersionUID = 5508512956753757169L;
-    // register center address
+
+    /**
+     * Register center address
+     */
     private String address;
 
-    // username to login register center
+    /**
+     * Username to login register center
+     */
     private String username;
 
-    // password to login register center
+    /**
+     * Password to login register center
+     */
     private String password;
 
-    // default port for register center
+    /**
+     * Default port for register center
+     */
     private Integer port;
 
-    // protocol for register center
+    /**
+     * Protocol for register center
+     */
     private String protocol;
 
-    // client impl
+    /**
+     * Network transmission type
+     */
     private String transporter;
 
     private String server;
@@ -55,42 +68,65 @@ public class RegistryConfig extends AbstractConfig {
 
     private String cluster;
 
+    /**
+     * The group the services registry in
+     */
     private String group;
 
     private String version;
 
-    // request timeout in milliseconds for register center
+    /**
+     * Request timeout in milliseconds for register center
+     */
     private Integer timeout;
 
-    // session timeout in milliseconds for register center
+    /**
+     * Session timeout in milliseconds for register center
+     */
     private Integer session;
 
-    // file for saving register center dynamic list
+    /**
+     * File for saving register center dynamic list
+     */
     private String file;
 
-    // wait time before stop
+    /**
+     * Wait time before stop
+     */
     private Integer wait;
 
-    // whether to check if register center is available when boot up
+    /**
+     * Whether to check if register center is available when boot up
+     */
     private Boolean check;
 
-    // whether to allow dynamic service to register on the register center
+    /**
+     * Whether to allow dynamic service to register on the register center
+     */
     private Boolean dynamic;
 
-    // whether to export service on the register center
+    /**
+     * Whether to export service on the register center
+     */
     private Boolean register;
 
-    // whether allow to subscribe service on the register center
+    /**
+     * Whether allow to subscribe service on the register center
+     */
     private Boolean subscribe;
 
-    // customized parameters
+    /**
+     * The customized parameters
+     */
     private Map<String, String> parameters;
 
-    // if it's default
+    /**
+     * Whether it's default
+     */
     private Boolean isDefault;
 
     /**
-     * simple the registry.
+     * Simple the registry.
      *
      * @since 2.7.0
      */
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
index 84b8188..0309ff0 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
@@ -72,30 +72,96 @@ public class ServiceConfig<T> extends AbstractServiceConfig 
{
 
     private static final long serialVersionUID = 3033787999037024738L;
 
+    /**
+     * The {@link Protocol} implementation with adaptive functionality,it will 
be different in different scenarios.
+     * A particular {@link Protocol} implementation is determined by the 
protocol attribute in the {@link URL}.
+     * For example:
+     *
+     * <li>when the url is 
registry://224.5.6.7:1234/org.apache.dubbo.registry.RegistryService?application=dubbo-sample,
+     * then the protocol is <b>RegistryProtocol</b></li>
+     *
+     * <li>when the url is 
dubbo://224.5.6.7:1234/org.apache.dubbo.config.api.DemoService?application=dubbo-sample,
 then
+     * the protocol is <b>DubboProtocol</b></li>
+     *
+     * Actually,when the {@link ExtensionLoader} init the {@link Protocol} 
instants,it will automatically wraps two
+     * layers, and eventually will get a <b>ProtocolFilterWrapper</b> or 
<b>ProtocolListenerWrapper</b>
+     */
     private static final Protocol protocol = 
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
 
+    /**
+     * A {@link ProxyFactory} implementation that will generate a exported 
service proxy,the JavassistProxyFactory is its
+     * default implementation
+     */
     private static final ProxyFactory proxyFactory = 
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
 
+    /**
+     * A random port cache, the different protocols who has no port specified 
have different random port
+     */
     private static final Map<String, Integer> RANDOM_PORT_MAP = new 
HashMap<String, Integer>();
 
+    /**
+     * A delayed exposure service timer
+     */
     private static final ScheduledExecutorService delayExportExecutor = 
Executors.newSingleThreadScheduledExecutor(new 
NamedThreadFactory("DubboServiceDelayExporter", true));
+
+    /**
+     * The urls of the services exported
+     */
     private final List<URL> urls = new ArrayList<URL>();
+
+    /**
+     * The exported services
+     */
     private final List<Exporter<?>> exporters = new ArrayList<Exporter<?>>();
-    // interface type
+
+    /**
+     * The interface name of the exported service
+     */
     private String interfaceName;
+
+    /**
+     * The interface class of the exported service
+     */
     private Class<?> interfaceClass;
-    // reference to interface impl
+
+    /**
+     * The reference of the interface implementation
+     */
     private T ref;
-    // service name
+
+    /**
+     * The service name
+     */
     private String path;
-    // method configuration
+
+    /**
+     * The method configuration
+     */
     private List<MethodConfig> methods;
+
+    /**
+     * The provider configuration
+     */
     private ProviderConfig provider;
+
+    /**
+     * The providerIds
+     */
     private String providerIds;
+
+    /**
+     * Whether the provider has been exported
+     */
     private transient volatile boolean exported;
 
+    /**
+     * The flag whether a service has unexported ,if the method unexported is 
invoked, the value is true
+     */
     private transient volatile boolean unexported;
 
+    /**
+     * whether it is a GenericService
+     */
     private volatile String generic;
 
     public ServiceConfig() {
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvoker.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvoker.java
index c0b93be..c106348 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvoker.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvoker.java
@@ -23,6 +23,10 @@ import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
 
+/**
+ *
+ * A Invoker wrapper that wrap the invoker and all the metadata (ServiceConfig)
+ */
 public class DelegateProviderMetaDataInvoker<T> implements Invoker {
     protected final Invoker<T> invoker;
     private ServiceConfig metadata;
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ReferenceConfigCache.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ReferenceConfigCache.java
index 0ced617..5ca9698 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ReferenceConfigCache.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ReferenceConfigCache.java
@@ -25,7 +25,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
 /**
- * a simple util class for cache {@link ReferenceConfig}.
+ * A simple util class for cache {@link ReferenceConfig}.
  * <p>
  * {@link ReferenceConfig} is a heavy Object, it's necessary to cache these 
object
  * for the framework which create {@link ReferenceConfig} frequently.
diff --git 
a/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MonitorFilter.java
 
b/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MonitorFilter.java
index a82fe54..d9d4b79 100644
--- 
a/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MonitorFilter.java
+++ 
b/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MonitorFilter.java
@@ -79,57 +79,64 @@ public class MonitorFilter implements Filter {
     // collect info
     private void collect(Invoker<?> invoker, Invocation invocation, Result 
result, String remoteHost, long start, boolean error) {
         try {
-            // ---- service statistics ----
-            long elapsed = System.currentTimeMillis() - start; // invocation 
cost
-            int concurrent = getConcurrent(invoker, invocation).get(); // 
current concurrent count
-            String application = 
invoker.getUrl().getParameter(Constants.APPLICATION_KEY);
-            String service = invoker.getInterface().getName(); // service name
-            String method = RpcUtils.getMethodName(invocation); // method name
-            String group = invoker.getUrl().getParameter(Constants.GROUP_KEY);
-            String version = 
invoker.getUrl().getParameter(Constants.VERSION_KEY);
-            URL url = invoker.getUrl().getUrlParameter(Constants.MONITOR_KEY);
-            Monitor monitor = monitorFactory.getMonitor(url);
+            URL monitorUrl = 
invoker.getUrl().getUrlParameter(Constants.MONITOR_KEY);
+            Monitor monitor = monitorFactory.getMonitor(monitorUrl);
             if (monitor == null) {
                 return;
             }
-            int localPort;
-            String remoteKey;
-            String remoteValue;
-            if 
(Constants.CONSUMER_SIDE.equals(invoker.getUrl().getParameter(Constants.SIDE_KEY)))
 {
-                // ---- for service consumer ----
-                localPort = 0;
-                remoteKey = MonitorService.PROVIDER;
-                remoteValue = invoker.getUrl().getAddress();
-            } else {
-                // ---- for service provider ----
-                localPort = invoker.getUrl().getPort();
-                remoteKey = MonitorService.CONSUMER;
-                remoteValue = remoteHost;
-            }
-            String input = "", output = "";
-            if (invocation.getAttachment(Constants.INPUT_KEY) != null) {
-                input = invocation.getAttachment(Constants.INPUT_KEY);
-            }
-            if (result != null && result.getAttachment(Constants.OUTPUT_KEY) 
!= null) {
-                output = result.getAttachment(Constants.OUTPUT_KEY);
-            }
-            monitor.collect(new URL(Constants.COUNT_PROTOCOL,
-                    NetUtils.getLocalHost(), localPort,
-                    service + "/" + method,
-                    MonitorService.APPLICATION, application,
-                    MonitorService.INTERFACE, service,
-                    MonitorService.METHOD, method,
-                    remoteKey, remoteValue,
-                    error ? MonitorService.FAILURE : MonitorService.SUCCESS, 
"1",
-                    MonitorService.ELAPSED, String.valueOf(elapsed),
-                    MonitorService.CONCURRENT, String.valueOf(concurrent),
-                    Constants.INPUT_KEY, input,
-                    Constants.OUTPUT_KEY, output,
-                    Constants.GROUP_KEY, group,
-                    Constants.VERSION_KEY, version));
+            URL statisticsURL = createStatisticsUrl(invoker, invocation, 
result, remoteHost, start, error);
+            monitor.collect(statisticsURL);
         } catch (Throwable t) {
-            logger.error("Failed to monitor count service " + invoker.getUrl() 
+ ", cause: " + t.getMessage(), t);
+            logger.warn("Failed to monitor count service " + invoker.getUrl() 
+ ", cause: " + t.getMessage(), t);
+        }
+    }
+
+    private URL createStatisticsUrl(Invoker<?> invoker, Invocation invocation, 
Result result, String remoteHost, long start, boolean error) {
+        // ---- service statistics ----
+        long elapsed = System.currentTimeMillis() - start; // invocation cost
+        int concurrent = getConcurrent(invoker, invocation).get(); // current 
concurrent count
+        String application = 
invoker.getUrl().getParameter(Constants.APPLICATION_KEY);
+        String service = invoker.getInterface().getName(); // service name
+        String method = RpcUtils.getMethodName(invocation); // method name
+        String group = invoker.getUrl().getParameter(Constants.GROUP_KEY);
+        String version = invoker.getUrl().getParameter(Constants.VERSION_KEY);
+
+        int localPort;
+        String remoteKey, remoteValue;
+        if 
(Constants.CONSUMER_SIDE.equals(invoker.getUrl().getParameter(Constants.SIDE_KEY)))
 {
+            // ---- for service consumer ----
+            localPort = 0;
+            remoteKey = MonitorService.PROVIDER;
+            remoteValue = invoker.getUrl().getAddress();
+        } else {
+            // ---- for service provider ----
+            localPort = invoker.getUrl().getPort();
+            remoteKey = MonitorService.CONSUMER;
+            remoteValue = remoteHost;
+        }
+
+        String input = "", output = "";
+        if (invocation.getAttachment(Constants.INPUT_KEY) != null) {
+            input = invocation.getAttachment(Constants.INPUT_KEY);
+        }
+        if (result != null && result.getAttachment(Constants.OUTPUT_KEY) != 
null) {
+            output = result.getAttachment(Constants.OUTPUT_KEY);
         }
+
+        return new URL(Constants.COUNT_PROTOCOL,
+                NetUtils.getLocalHost(), localPort,
+                service + Constants.PATH_SEPARATOR + method,
+                MonitorService.APPLICATION, application,
+                MonitorService.INTERFACE, service,
+                MonitorService.METHOD, method,
+                remoteKey, remoteValue,
+                error ? MonitorService.FAILURE : MonitorService.SUCCESS, "1",
+                MonitorService.ELAPSED, String.valueOf(elapsed),
+                MonitorService.CONCURRENT, String.valueOf(concurrent),
+                Constants.INPUT_KEY, input,
+                Constants.OUTPUT_KEY, output,
+                Constants.GROUP_KEY, group,
+                Constants.VERSION_KEY, version);
     }
 
     // concurrent counter
diff --git 
a/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/DubboMonitor.java
 
b/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/DubboMonitor.java
index 6dd4415..1e441e5 100644
--- 
a/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/DubboMonitor.java
+++ 
b/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/DubboMonitor.java
@@ -44,6 +44,9 @@ public class DubboMonitor implements Monitor {
 
     private static final int LENGTH = 10;
 
+    /**
+     * The timer sends the statistics data to monitor center
+     */
     private final ScheduledExecutorService scheduledExecutorService = 
Executors.newScheduledThreadPool(3, new 
NamedThreadFactory("DubboMonitorSendTimer", true));
 
     private final ScheduledFuture<?> sendFuture;
@@ -61,15 +64,12 @@ public class DubboMonitor implements Monitor {
         this.monitorService = monitorService;
         this.monitorInterval = 
monitorInvoker.getUrl().getPositiveParameter("interval", 60000);
         // collect timer for collecting statistics data
-        sendFuture = scheduledExecutorService.scheduleWithFixedDelay(new 
Runnable() {
-            @Override
-            public void run() {
+        sendFuture = scheduledExecutorService.scheduleWithFixedDelay(() -> {
+            try {
                 // collect data
-                try {
-                    send();
-                } catch (Throwable t) {
-                    logger.error("Unexpected error occur at send statistic, 
cause: " + t.getMessage(), t);
-                }
+                send();
+            } catch (Throwable t) {
+                logger.error("Unexpected error occur at send statistic, cause: 
" + t.getMessage(), t);
             }
         }, monitorInterval, monitorInterval, TimeUnit.MILLISECONDS);
     }
@@ -92,7 +92,7 @@ public class DubboMonitor implements Monitor {
             long maxOutput = numbers[7];
             long maxElapsed = numbers[8];
             long maxConcurrent = numbers[9];
-            String version = getUrl().getParameter(Constants.DEFAULT_PROTOCOL);
+            String protocol = 
getUrl().getParameter(Constants.DEFAULT_PROTOCOL);
 
             // send statistics data
             URL url = statistics.getUrl()
@@ -107,7 +107,7 @@ public class DubboMonitor implements Monitor {
                             MonitorService.MAX_OUTPUT, 
String.valueOf(maxOutput),
                             MonitorService.MAX_ELAPSED, 
String.valueOf(maxElapsed),
                             MonitorService.MAX_CONCURRENT, 
String.valueOf(maxConcurrent),
-                            Constants.DEFAULT_PROTOCOL, version
+                            Constants.DEFAULT_PROTOCOL, protocol
                     );
             monitorService.collect(url);
 

Reply via email to