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

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

commit dbca54ca237b16e157ada4aa2b98eb29117fb2ba
Merge: d11b876 38a6511
Author: ken.lj <[email protected]>
AuthorDate: Thu Nov 15 11:33:24 2018 +0800

    Merge branch 'master' into dev-metadata
    
    # Conflicts:
    #   dubbo-all/pom.xml
    #   dubbo-bootstrap/pom.xml
    #   
dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java
    #   
dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractConfig.java
    #   
dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
    #   
dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ProtocolConfig.java
    #   
dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
    #   
dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
    #   
dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ServiceBean.java
    #   
dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigConfiguration.java
    #   
dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/initializer/DubboApplicationListenerTest.java
    #   
dubbo-demo/dubbo-demo-consumer/src/main/java/org/apache/dubbo/demo/consumer/Consumer.java

 README.md                                          |   2 +
 codestyle/checkstyle.xml                           |   6 +
 codestyle/dubbo_codestyle_for_idea.xml             |   2 -
 dubbo-bom/pom.xml                                  |   5 -
 .../apache/dubbo/config/AbstractConfigTest.java    |   3 +-
 .../dubbo/config/AbstractInterfaceConfigTest.java  |  27 ++--
 .../dubbo/config/AbstractMethodConfigTest.java     |   7 +
 .../org/apache/dubbo/config/ServiceConfigTest.java |  12 ++
 .../java/org/apache/dubbo/common/Constants.java    |  17 +++
 .../org/apache/dubbo/common/compiler/Compiler.java |   1 -
 .../common/compiler/support/AdaptiveCompiler.java  |   1 -
 .../dubbo/common/extension/DisableInject.java      |  16 ++-
 .../dubbo/common/extension/ExtensionLoader.java    |  21 ++-
 .../apache/dubbo/common/logger/jcl/JclLogger.java  |   1 +
 .../dubbo/common/logger/jcl/JclLoggerAdapter.java  |   1 +
 .../support/eager/EagerThreadPoolExecutor.java     |   2 +-
 .../dubbo/common/timer/HashedWheelTimer.java       |  13 +-
 .../java/org/apache/dubbo/common/timer/Timer.java  |   7 +
 .../Compiler.java => utils/ArrayUtils.java}        |  84 ++++++------
 .../org/apache/dubbo/common/utils/StringUtils.java | 118 +++++++++++------
 .../common/extension/ExtensionLoaderTest.java      |  13 +-
 .../common/extension/injection/InjectExt.java      |  13 +-
 .../extension/injection/impl/InjectExtImpl.java    |  60 +++++++++
 .../apache/dubbo/common/utils/ArrayUtilsTest.java  |  38 +++---
 .../apache/dubbo/common/utils/StringUtilsTest.java |  30 ++++-
 ...ache.dubbo.common.extension.injection.InjectExt |   1 +
 .../main/java/com/alibaba/dubbo/common/URL.java    | 103 ++++++++++++++-
 .../alibaba/dubbo/common/status/StatusChecker.java |   1 +
 .../spring/context/annotation/EnableDubbo.java     |   1 +
 .../java/com/alibaba/dubbo/monitor/Monitor.java    |   1 +
 .../java/com/alibaba/dubbo/registry/Registry.java  |   1 +
 .../java/com/alibaba/dubbo/remoting/Channel.java   |   2 +
 .../main/java/com/alibaba/dubbo/rpc/Exporter.java  |   1 +
 .../main/java/com/alibaba/dubbo/rpc/Filter.java    |   1 +
 .../java/com/alibaba/dubbo/rpc/Invocation.java     |   2 +
 .../main/java/com/alibaba/dubbo/rpc/Invoker.java   |   2 +
 .../com/alibaba/dubbo/rpc/cluster/Directory.java   |   5 +-
 .../java/com/alibaba/dubbo/rpc/cluster/Router.java |   1 +
 ...atibleReferenceAnnotationBeanPostProcessor.java |   4 +-
 .../annotation/CompatibleReferenceBeanBuilder.java |   4 +-
 ...mpatibleServiceAnnotationBeanPostProcessor.java |   4 +-
 .../CompatibleDubboComponentScanRegistrar.java     |   1 +
 .../CompatibleAnnotationBeanDefinitionParser.java  |   3 +-
 .../org/apache/dubbo/config/AbstractConfig.java    |   5 +-
 .../dubbo/config/AbstractInterfaceConfig.java      |  51 +++++---
 .../apache/dubbo/config/AbstractMethodConfig.java  |  23 +++-
 .../org/apache/dubbo/config/ProtocolConfig.java    |   2 +-
 .../org/apache/dubbo/config/ReferenceConfig.java   |   3 +-
 .../org/apache/dubbo/config/ServiceConfig.java     |  13 +-
 dubbo-config/dubbo-config-spring/pom.xml           |   7 +-
 .../apache/dubbo/config/spring/AnnotationBean.java |  24 ++--
 .../apache/dubbo/config/spring/ReferenceBean.java  |   1 +
 .../apache/dubbo/config/spring/ServiceBean.java    |  29 +----
 .../AbstractAnnotationConfigBeanBuilder.java       |   1 +
 .../DubboConfigBindingBeanPostProcessor.java       |   1 +
 .../ReferenceAnnotationBeanPostProcessor.java      |   9 +-
 .../factory/annotation/ReferenceBeanBuilder.java   |   1 +
 .../ServiceAnnotationBeanPostProcessor.java        |   5 +-
 .../context/annotation/DubboComponentScan.java     |   1 +
 .../annotation/DubboComponentScanRegistrar.java    |   1 +
 .../annotation/DubboConfigBindingRegistrar.java    |   1 +
 .../annotation/DubboConfigBindingsRegistrar.java   |   1 +
 .../DubboConfigConfigurationSelector.java          |   1 +
 .../spring/context/annotation/EnableDubbo.java     |   1 +
 .../context/annotation/EnableDubboConfig.java      |   1 +
 .../annotation/EnableDubboConfigBinding.java       |   1 +
 .../properties/DefaultDubboConfigBinder.java       |   1 +
 .../context/properties/DubboConfigBinder.java      |   1 +
 .../converter/StringArrayToMapConverter.java       |   1 +
 .../spring/extension/SpringExtensionFactory.java   |  33 ++++-
 .../DubboApplicationContextInitializer.java        |  39 ------
 .../initializer/DubboApplicationListener.java      |  49 -------
 .../spring/initializer/DubboContextListener.java   |  72 ----------
 .../schema/AnnotationBeanDefinitionParser.java     |   1 +
 .../spring/schema/DubboNamespaceHandler.java       |   1 +
 .../spring/status/DataSourceStatusChecker.java     |   1 +
 .../config/spring/status/SpringStatusChecker.java  |   1 +
 .../dubbo/config/spring/util/BeanFactoryUtils.java |  28 ++++
 .../src/main/resources/META-INF/compat/dubbo.xsd   |  10 ++
 .../src/main/resources/META-INF/dubbo.xsd          |  10 ++
 .../src/main/resources/META-INF/web-fragment.xml   |  22 ----
 .../org/apache/dubbo/config/spring/ConfigTest.java |  33 +++++
 .../annotation/provider/HelloServiceImpl.java      |   2 +-
 .../DubboApplicationContextInitializerTest.java    |  88 -------------
 .../initializer/DubboApplicationListenerTest.java  |  59 ---------
 dubbo-container/dubbo-container-spring/pom.xml     |   7 +-
 .../dubbo/container/spring/SpringContainer.java    |   6 +-
 dubbo-distribution/pom.xml                         |   5 -
 .../org/apache/dubbo/cache/filter/CacheFilter.java |   4 +-
 .../dubbo/cache/support/expiring/ExpiringMap.java  |   2 +-
 .../cache/support/jcache/JCacheFactoryTest.java    |   2 +-
 .../org/apache/dubbo/metrics/MetricRegistry.java   |   1 -
 .../dubbo/qos/protocol/QosProtocolWrapper.java     |   9 +-
 .../java/org/apache/dubbo/qos/server/Server.java   |   1 +
 .../qos/server/handler/HttpProcessHandler.java     |   1 +
 .../qos/server/handler/LocalHostPermitHandler.java |   1 -
 .../qos/server/handler/TelnetProcessHandler.java   |   1 -
 .../java/org/apache/dubbo/qos/textui/TTable.java   |   6 +-
 .../java/org/apache/dubbo/qos/textui/TTree.java    |   2 +-
 .../registry/support/FailbackRegistryTest.java     |  23 ++++
 .../exchange/support/header/AbstractTimerTask.java |  87 +++++++++++++
 .../support/header/HeaderExchangeClient.java       |  67 +++++-----
 .../support/header/HeaderExchangeServer.java       |  76 +++++------
 .../exchange/support/header/HeartBeatTask.java     |  97 --------------
 .../support/header/HeartbeatTimerTask.java         |  62 +++++++++
 .../support/header/ReconnectTimerTask.java         |  61 +++++++++
 .../telnet/support/command/LogTelnetHandler.java   |   1 -
 .../transport/dispatcher/ChannelHandlers.java      |   1 -
 .../exchange/support/header/HeartBeatTaskTest.java |  29 +++--
 .../support/header/HeartbeatHandlerTest.java       |   8 +-
 .../transport/netty/NettyClientToServerTest.java   |  11 +-
 .../transport/netty4/NettyBackedChannelBuffer.java |   1 +
 .../transport/netty4/NettyClientHandler.java       |   4 +-
 .../transport/netty4/NettyServerHandler.java       |   2 +-
 .../transport/netty4/logging/MessageFormatter.java |   1 -
 .../transport/netty4/NettyClientToServerTest.java  |  11 +-
 .../zookeeper/zkclient/ZkClientWrapper.java        |   7 +-
 .../alibaba/dubbo/rpc/service/GenericService.java  |   1 +
 .../java/org/apache/dubbo/rpc/AbstractResult.java  |   1 +
 .../org/apache/dubbo/rpc/AsyncContextImpl.java     |   1 +
 .../java/org/apache/dubbo/rpc/AsyncRpcResult.java  |   1 +
 .../apache/dubbo/rpc/filter/AccessLogFilter.java   |   3 +-
 .../dubbo/rpc/proxy/AbstractProxyFactory.java      |   4 +-
 .../org/apache/dubbo/rpc/support/MockInvoker.java  | 145 +++++++++++++--------
 .../rpc/protocol/dubbo/filter/TraceFilter.java     |   1 +
 .../protocol/dubbo/telnet/InvokeTelnetHandler.java |   1 +
 .../protocol/dubbo/telnet/LogTelnetHandler.java    |   1 -
 .../rpc/protocol/dubbo/DubboProtocolTest.java      |   9 +-
 .../dubbo/ReferenceCountExchangeClientTest.java    |   7 +
 .../hessian/DubboHessianURLConnectionFactory.java  |   1 +
 .../rpc/protocol/hessian/HessianProtocol.java      |   2 +-
 .../dubbo/rpc/protocol/http/HttpProtocol.java      |   1 +
 .../rpc/protocol/http/HttpRemoteInvocation.java    |   1 +
 .../dubbo/rpc/protocol/rest/RpcContextFilter.java  |   1 +
 .../swagger/DubboSwaggerApiListingResource.java    |   7 +-
 .../integration/swagger/DubboSwaggerService.java   |   2 +-
 .../rpc/protocol/rmi/RmiRemoteInvocation.java      |   1 +
 .../dubbo/rpc/protocol/thrift/ThriftCodec.java     |   1 -
 .../serialize/fastjson/FastJsonObjectOutput.java   |   1 +
 .../dubbo/common/serialize/fst/FstFactory.java     |   1 +
 .../serialize/hessian2/Hessian2ObjectInput.java    |   3 +-
 .../serialize/hessian2/Hessian2ObjectOutput.java   |   3 +-
 .../common/serialize/java/JavaObjectOutput.java    |   1 -
 .../common/serialize/kryo/CompatibleKryo.java      |   7 +-
 .../serialize/kryo/utils/AbstractKryoFactory.java  |   5 +-
 .../protostuff/ProtostuffObjectInput.java          |   5 +-
 .../protostuff/ProtostuffObjectOutput.java         |   5 +-
 .../serialize/protostuff/utils/WrapperUtils.java   |   5 +-
 .../dubbo/test/Spring3CompatibilityTest.java       |   1 +
 .../dubbo/test/consumer/ConsumerConfiguration.java |   1 +
 .../dubbo/test/provider/ProviderConfiguration.java |   1 +
 pom.xml                                            |   1 -
 152 files changed, 1224 insertions(+), 878 deletions(-)

diff --cc 
dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
index 3552f4d,31f72e6..d69b6aa
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
@@@ -542,10 -532,13 +542,16 @@@ public class ExtensionLoader<T> 
                      if (method.getName().startsWith("set")
                              && method.getParameterTypes().length == 1
                              && Modifier.isPublic(method.getModifiers())) {
+                         /**
+                          * Check {@link DisableInject} to see if we need auto 
injection for this property
+                          */
+                         if (method.getAnnotation(DisableInject.class) != 
null) {
+                             continue;
+                         }
                          Class<?> pt = method.getParameterTypes()[0];
 +                        if (ReflectUtils.isPrimitives(pt)) {
 +                            continue;
 +                        }
                          try {
                              String property = method.getName().length() > 3 ? 
method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4) 
: "";
                              Object object = objectFactory.getExtension(pt, 
property);
diff --cc 
dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractConfig.java
index 243e8d2,fada00e..5af184d
--- 
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
@@@ -1,627 -1,535 +1,628 @@@
 -/*
 - * 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.extension.ExtensionLoader;
 -import org.apache.dubbo.common.logger.Logger;
 -import org.apache.dubbo.common.logger.LoggerFactory;
 -import org.apache.dubbo.common.utils.CollectionUtils;
 -import org.apache.dubbo.common.utils.ConfigUtils;
 -import org.apache.dubbo.common.utils.ReflectUtils;
 -import org.apache.dubbo.common.utils.StringUtils;
 -import org.apache.dubbo.config.support.Parameter;
 -import org.apache.dubbo.rpc.model.ConsumerMethodModel;
 -
 -import java.io.Serializable;
 -import java.lang.reflect.Method;
 -import java.lang.reflect.Modifier;
 -import java.util.HashMap;
 -import java.util.Map;
 -import java.util.regex.Matcher;
 -import java.util.regex.Pattern;
 -
 -/**
 - * Utility methods and public methods for parsing configuration
 - *
 - * @export
 - */
 -public abstract class AbstractConfig implements Serializable {
 -
 -    protected static final Logger logger = 
LoggerFactory.getLogger(AbstractConfig.class);
 -    private static final long serialVersionUID = 4267533505537413570L;
 -    private static final int MAX_LENGTH = 200;
 -
 -    private static final int MAX_PATH_LENGTH = 200;
 -
 -    private static final Pattern PATTERN_NAME = 
Pattern.compile("[\\-._0-9a-zA-Z]+");
 -
 -    private static final Pattern PATTERN_MULTI_NAME = 
Pattern.compile("[,\\-._0-9a-zA-Z]+");
 -
 -    private static final Pattern PATTERN_METHOD_NAME = 
Pattern.compile("[a-zA-Z][0-9a-zA-Z]*");
 -
 -    private static final Pattern PATTERN_PATH = 
Pattern.compile("[/\\-$._0-9a-zA-Z]+");
 -
 -    private static final Pattern PATTERN_NAME_HAS_SYMBOL = 
Pattern.compile("[:*,\\s/\\-._0-9a-zA-Z]+");
 -
 -    private static final Pattern PATTERN_KEY = 
Pattern.compile("[*,\\-._0-9a-zA-Z]+");
 -    private static final Map<String, String> legacyProperties = new 
HashMap<String, String>();
 -    private static final String[] SUFFIXES = new String[]{"Config", "Bean"};
 -
 -    static {
 -        legacyProperties.put("dubbo.protocol.name", "dubbo.service.protocol");
 -        legacyProperties.put("dubbo.protocol.host", 
"dubbo.service.server.host");
 -        legacyProperties.put("dubbo.protocol.port", 
"dubbo.service.server.port");
 -        legacyProperties.put("dubbo.protocol.threads", 
"dubbo.service.max.thread.pool.size");
 -        legacyProperties.put("dubbo.consumer.timeout", 
"dubbo.service.invoke.timeout");
 -        legacyProperties.put("dubbo.consumer.retries", 
"dubbo.service.max.retry.providers");
 -        legacyProperties.put("dubbo.consumer.check", 
"dubbo.service.allow.no.provider");
 -        legacyProperties.put("dubbo.service.url", "dubbo.service.address");
 -
 -        // this is only for compatibility
 -        
Runtime.getRuntime().addShutdownHook(DubboShutdownHook.getDubboShutdownHook());
 -    }
 -
 -    protected String id;
 -
 -    private static String convertLegacyValue(String key, String value) {
 -        if (value != null && value.length() > 0) {
 -            if ("dubbo.service.max.retry.providers".equals(key)) {
 -                return String.valueOf(Integer.parseInt(value) - 1);
 -            } else if ("dubbo.service.allow.no.provider".equals(key)) {
 -                return String.valueOf(!Boolean.parseBoolean(value));
 -            }
 -        }
 -        return value;
 -    }
 -
 -    protected static void appendProperties(AbstractConfig config) {
 -        if (config == null) {
 -            return;
 -        }
 -        String prefix = "dubbo." + getTagName(config.getClass()) + ".";
 -        Method[] methods = config.getClass().getMethods();
 -        for (Method method : methods) {
 -            try {
 -                String name = method.getName();
 -                if (name.length() > 3 && name.startsWith("set") && 
Modifier.isPublic(method.getModifiers())
 -                        && method.getParameterTypes().length == 1 && 
isPrimitive(method.getParameterTypes()[0])) {
 -                    String property = 
StringUtils.camelToSplitName(name.substring(3, 4).toLowerCase() + 
name.substring(4), ".");
 -
 -                    String value = null;
 -                    if (config.getId() != null && config.getId().length() > 
0) {
 -                        String pn = prefix + config.getId() + "." + property;
 -                        value = System.getProperty(pn);
 -                        if (!StringUtils.isBlank(value)) {
 -                            logger.info("Use System Property " + pn + " to 
config dubbo");
 -                        }
 -                    }
 -                    if (value == null || value.length() == 0) {
 -                        String pn = prefix + property;
 -                        value = System.getProperty(pn);
 -                        if (!StringUtils.isBlank(value)) {
 -                            logger.info("Use System Property " + pn + " to 
config dubbo");
 -                        }
 -                    }
 -                    if (value == null || value.length() == 0) {
 -                        Method getter;
 -                        try {
 -                            getter = config.getClass().getMethod("get" + 
name.substring(3));
 -                        } catch (NoSuchMethodException e) {
 -                            try {
 -                                getter = config.getClass().getMethod("is" + 
name.substring(3));
 -                            } catch (NoSuchMethodException e2) {
 -                                getter = null;
 -                            }
 -                        }
 -                        if (getter != null) {
 -                            if (getter.invoke(config) == null) {
 -                                if (config.getId() != null && 
config.getId().length() > 0) {
 -                                    value = ConfigUtils.getProperty(prefix + 
config.getId() + "." + property);
 -                                }
 -                                if (value == null || value.length() == 0) {
 -                                    value = ConfigUtils.getProperty(prefix + 
property);
 -                                }
 -                                if (value == null || value.length() == 0) {
 -                                    String legacyKey = 
legacyProperties.get(prefix + property);
 -                                    if (legacyKey != null && 
legacyKey.length() > 0) {
 -                                        value = convertLegacyValue(legacyKey, 
ConfigUtils.getProperty(legacyKey));
 -                                    }
 -                                }
 -
 -                            }
 -                        }
 -                    }
 -                    if (value != null && value.length() > 0) {
 -                        method.invoke(config, 
convertPrimitive(method.getParameterTypes()[0], value));
 -                    }
 -                }
 -            } catch (Exception e) {
 -                logger.error(e.getMessage(), e);
 -            }
 -        }
 -    }
 -
 -    private static String getTagName(Class<?> cls) {
 -        String tag = cls.getSimpleName();
 -        for (String suffix : SUFFIXES) {
 -            if (tag.endsWith(suffix)) {
 -                tag = tag.substring(0, tag.length() - suffix.length());
 -                break;
 -            }
 -        }
 -        tag = tag.toLowerCase();
 -        return tag;
 -    }
 -
 -    protected static void appendParameters(Map<String, String> parameters, 
Object config) {
 -        appendParameters(parameters, config, null);
 -    }
 -
 -    @SuppressWarnings("unchecked")
 -    protected static void appendParameters(Map<String, String> parameters, 
Object config, String prefix) {
 -        if (config == null) {
 -            return;
 -        }
 -        Method[] methods = config.getClass().getMethods();
 -        for (Method method : methods) {
 -            try {
 -                String name = method.getName();
 -                if ((name.startsWith("get") || name.startsWith("is"))
 -                        && !"getClass".equals(name)
 -                        && Modifier.isPublic(method.getModifiers())
 -                        && method.getParameterTypes().length == 0
 -                        && isPrimitive(method.getReturnType())) {
 -                    Parameter parameter = 
method.getAnnotation(Parameter.class);
 -                    if (method.getReturnType() == Object.class || parameter 
!= null && parameter.excluded()) {
 -                        continue;
 -                    }
 -                    int i = name.startsWith("get") ? 3 : 2;
 -                    String prop = 
StringUtils.camelToSplitName(name.substring(i, i + 1).toLowerCase() + 
name.substring(i + 1), ".");
 -                    String key;
 -                    if (parameter != null && parameter.key().length() > 0) {
 -                        key = parameter.key();
 -                    } else {
 -                        key = prop;
 -                    }
 -                    Object value = method.invoke(config);
 -                    String str = String.valueOf(value).trim();
 -                    if (value != null && str.length() > 0) {
 -                        if (parameter != null && parameter.escaped()) {
 -                            str = URL.encode(str);
 -                        }
 -                        if (parameter != null && parameter.append()) {
 -                            String pre = parameters.get(Constants.DEFAULT_KEY 
+ "." + key);
 -                            if (pre != null && pre.length() > 0) {
 -                                str = pre + "," + str;
 -                            }
 -                            pre = parameters.get(key);
 -                            if (pre != null && pre.length() > 0) {
 -                                str = pre + "," + str;
 -                            }
 -                        }
 -                        if (prefix != null && prefix.length() > 0) {
 -                            key = prefix + "." + key;
 -                        }
 -                        parameters.put(key, str);
 -                    } else if (parameter != null && parameter.required()) {
 -                        throw new 
IllegalStateException(config.getClass().getSimpleName() + "." + key + " == 
null");
 -                    }
 -                } else if ("getParameters".equals(name)
 -                        && Modifier.isPublic(method.getModifiers())
 -                        && method.getParameterTypes().length == 0
 -                        && method.getReturnType() == Map.class) {
 -                    Map<String, String> map = (Map<String, String>) 
method.invoke(config, new Object[0]);
 -                    if (map != null && map.size() > 0) {
 -                        String pre = (prefix != null && prefix.length() > 0 ? 
prefix + "." : "");
 -                        for (Map.Entry<String, String> entry : 
map.entrySet()) {
 -                            parameters.put(pre + entry.getKey().replace('-', 
'.'), entry.getValue());
 -                        }
 -                    }
 -                }
 -            } catch (Exception e) {
 -                throw new IllegalStateException(e.getMessage(), e);
 -            }
 -        }
 -    }
 -
 -    protected static void appendAttributes(Map<String, Object> parameters, 
Object config) {
 -        appendAttributes(parameters, config, null);
 -    }
 -
 -    protected static void appendAttributes(Map<String, Object> parameters, 
Object config, String prefix) {
 -        if (config == null) {
 -            return;
 -        }
 -        Method[] methods = config.getClass().getMethods();
 -        for (Method method : methods) {
 -            try {
 -                Parameter parameter = method.getAnnotation(Parameter.class);
 -                if (parameter == null || !parameter.attribute()) {
 -                    continue;
 -                }
 -                String name = method.getName();
 -                if ((name.startsWith("get") || name.startsWith("is"))
 -                        && !"getClass".equals(name)
 -                        && Modifier.isPublic(method.getModifiers())
 -                        && method.getParameterTypes().length == 0
 -                        && isPrimitive(method.getReturnType())) {
 -                    String key;
 -                    if (parameter.key().length() > 0) {
 -                        key = parameter.key();
 -                    } else {
 -                        int i = name.startsWith("get") ? 3 : 2;
 -                        key = name.substring(i, i + 1).toLowerCase() + 
name.substring(i + 1);
 -                    }
 -                    Object value = method.invoke(config);
 -                    if (value != null) {
 -                        if (prefix != null && prefix.length() > 0) {
 -                            key = prefix + "." + key;
 -                        }
 -                        parameters.put(key, value);
 -                    }
 -                }
 -            } catch (Exception e) {
 -                throw new IllegalStateException(e.getMessage(), e);
 -            }
 -        }
 -    }
 -
 -    protected static ConsumerMethodModel.AsyncMethodInfo 
convertMethodConfig2AyncInfo(MethodConfig methodConfig) {
 -        if (methodConfig == null || (methodConfig.getOninvoke() == null && 
methodConfig.getOnreturn() == null && methodConfig.getOnthrow() == null)) {
 -            return null;
 -        }
 -
 -        //check config conflict
 -        if (Boolean.FALSE.equals(methodConfig.isReturn()) && 
(methodConfig.getOnreturn() != null || methodConfig.getOnthrow() != null)) {
 -            throw new IllegalStateException("method config error : return 
attribute must be set true when onreturn or onthrow has been set.");
 -        }
 -
 -        ConsumerMethodModel.AsyncMethodInfo asyncMethodInfo = new 
ConsumerMethodModel.AsyncMethodInfo();
 -
 -        asyncMethodInfo.setOninvokeInstance(methodConfig.getOninvoke());
 -        asyncMethodInfo.setOnreturnInstance(methodConfig.getOnreturn());
 -        asyncMethodInfo.setOnthrowInstance(methodConfig.getOnthrow());
 -
 -        try {
 -            String oninvokeMethod = methodConfig.getOninvokeMethod();
 -            if (StringUtils.isNotEmpty(oninvokeMethod)) {
 -                
asyncMethodInfo.setOninvokeMethod(getMethodByName(methodConfig.getOninvoke().getClass(),
 oninvokeMethod));
 -            }
 -
 -            String onreturnMethod = methodConfig.getOnreturnMethod();
 -            if (StringUtils.isNotEmpty(onreturnMethod)) {
 -                
asyncMethodInfo.setOnreturnMethod(getMethodByName(methodConfig.getOnreturn().getClass(),
 onreturnMethod));
 -            }
 -
 -            String onthrowMethod = methodConfig.getOnthrowMethod();
 -            if (StringUtils.isNotEmpty(onthrowMethod)) {
 -                
asyncMethodInfo.setOnthrowMethod(getMethodByName(methodConfig.getOnthrow().getClass(),
 onthrowMethod));
 -            }
 -        } catch (Exception e) {
 -            throw new IllegalStateException(e.getMessage(), e);
 -        }
 -
 -        return asyncMethodInfo;
 -    }
 -
 -    private static Method getMethodByName(Class<?> clazz, String methodName) {
 -        try {
 -            return ReflectUtils.findMethodByMethodName(clazz, methodName);
 -        } catch (Exception e) {
 -            throw new IllegalStateException(e);
 -        }
 -    }
 -
 -    private static boolean isPrimitive(Class<?> type) {
 -        return type.isPrimitive()
 -                || type == String.class
 -                || type == Character.class
 -                || type == Boolean.class
 -                || type == Byte.class
 -                || type == Short.class
 -                || type == Integer.class
 -                || type == Long.class
 -                || type == Float.class
 -                || type == Double.class
 -                || type == Object.class;
 -    }
 -
 -    private static Object convertPrimitive(Class<?> type, String value) {
 -        if (type == char.class || type == Character.class) {
 -            return value.length() > 0 ? value.charAt(0) : '\0';
 -        } else if (type == boolean.class || type == Boolean.class) {
 -            return Boolean.valueOf(value);
 -        } else if (type == byte.class || type == Byte.class) {
 -            return Byte.valueOf(value);
 -        } else if (type == short.class || type == Short.class) {
 -            return Short.valueOf(value);
 -        } else if (type == int.class || type == Integer.class) {
 -            return Integer.valueOf(value);
 -        } else if (type == long.class || type == Long.class) {
 -            return Long.valueOf(value);
 -        } else if (type == float.class || type == Float.class) {
 -            return Float.valueOf(value);
 -        } else if (type == double.class || type == Double.class) {
 -            return Double.valueOf(value);
 -        }
 -        return value;
 -    }
 -
 -    protected static void checkExtension(Class<?> type, String property, 
String value) {
 -        checkName(property, value);
 -        if (value != null && value.length() > 0
 -                && 
!ExtensionLoader.getExtensionLoader(type).hasExtension(value)) {
 -            throw new IllegalStateException("No such extension " + value + " 
for " + property + "/" + type.getName());
 -        }
 -    }
 -
 -    protected static void checkMultiExtension(Class<?> type, String property, 
String value) {
 -        checkMultiName(property, value);
 -        if (value != null && value.length() > 0) {
 -            String[] values = value.split("\\s*[,]+\\s*");
 -            for (String v : values) {
 -                if (v.startsWith(Constants.REMOVE_VALUE_PREFIX)) {
 -                    v = v.substring(1);
 -                }
 -                if (Constants.DEFAULT_KEY.equals(v)) {
 -                    continue;
 -                }
 -                if 
(!ExtensionLoader.getExtensionLoader(type).hasExtension(v)) {
 -                    throw new IllegalStateException("No such extension " + v 
+ " for " + property + "/" + type.getName());
 -                }
 -            }
 -        }
 -    }
 -
 -    protected static void checkLength(String property, String value) {
 -        checkProperty(property, value, MAX_LENGTH, null);
 -    }
 -
 -    protected static void checkPathLength(String property, String value) {
 -        checkProperty(property, value, MAX_PATH_LENGTH, null);
 -    }
 -
 -    protected static void checkName(String property, String value) {
 -        checkProperty(property, value, MAX_LENGTH, PATTERN_NAME);
 -    }
 -
 -    protected static void checkNameHasSymbol(String property, String value) {
 -        checkProperty(property, value, MAX_LENGTH, PATTERN_NAME_HAS_SYMBOL);
 -    }
 -
 -    protected static void checkKey(String property, String value) {
 -        checkProperty(property, value, MAX_LENGTH, PATTERN_KEY);
 -    }
 -
 -    protected static void checkMultiName(String property, String value) {
 -        checkProperty(property, value, MAX_LENGTH, PATTERN_MULTI_NAME);
 -    }
 -
 -    protected static void checkPathName(String property, String value) {
 -        checkProperty(property, value, MAX_PATH_LENGTH, PATTERN_PATH);
 -    }
 -
 -    protected static void checkMethodName(String property, String value) {
 -        checkProperty(property, value, MAX_LENGTH, PATTERN_METHOD_NAME);
 -    }
 -
 -    protected static void checkParameterName(Map<String, String> parameters) {
 -        if (parameters == null || parameters.size() == 0) {
 -            return;
 -        }
 -        for (Map.Entry<String, String> entry : parameters.entrySet()) {
 -            checkNameHasSymbol(entry.getKey(), entry.getValue());
 -        }
 -    }
 -
 -    protected static void checkProperty(String property, String value, int 
maxlength, Pattern pattern) {
 -        if (value == null || value.length() == 0) {
 -            return;
 -        }
 -        if (value.length() > maxlength) {
 -            throw new IllegalStateException("Invalid " + property + "=\"" + 
value + "\" is longer than " + maxlength);
 -        }
 -        if (pattern != null) {
 -            Matcher matcher = pattern.matcher(value);
 -            if (!matcher.matches()) {
 -                throw new IllegalStateException("Invalid " + property + "=\"" 
+ value + "\" contains illegal " +
 -                        "character, only digit, letter, '-', '_' or '.' is 
legal.");
 -            }
 -        }
 -    }
 -
 -    @Parameter(excluded = true)
 -    public String getId() {
 -        return id;
 -    }
 -
 -    public void setId(String id) {
 -        this.id = id;
 -    }
 -
 -    protected void appendAnnotation(Class<?> annotationClass, Object 
annotation) {
 -        Method[] methods = annotationClass.getMethods();
 -        for (Method method : methods) {
 -            if (method.getDeclaringClass() != Object.class
 -                    && method.getReturnType() != void.class
 -                    && method.getParameterTypes().length == 0
 -                    && Modifier.isPublic(method.getModifiers())
 -                    && !Modifier.isStatic(method.getModifiers())) {
 -                try {
 -                    String property = method.getName();
 -                    if ("interfaceClass".equals(property) || 
"interfaceName".equals(property)) {
 -                        property = "interface";
 -                    }
 -                    String setter = "set" + property.substring(0, 
1).toUpperCase() + property.substring(1);
 -                    Object value = method.invoke(annotation);
 -                    if (value != null && 
!value.equals(method.getDefaultValue())) {
 -                        Class<?> parameterType = 
ReflectUtils.getBoxedClass(method.getReturnType());
 -                        if ("filter".equals(property) || 
"listener".equals(property)) {
 -                            parameterType = String.class;
 -                            value = StringUtils.join((String[]) value, ",");
 -                        } else if ("parameters".equals(property)) {
 -                            parameterType = Map.class;
 -                            value = CollectionUtils.toStringMap((String[]) 
value);
 -                        }
 -                        try {
 -                            Method setterMethod = 
getClass().getMethod(setter, parameterType);
 -                            setterMethod.invoke(this, value);
 -                        } catch (NoSuchMethodException e) {
 -                            // ignore
 -                        }
 -                    }
 -                } catch (Throwable e) {
 -                    logger.error(e.getMessage(), e);
 -                }
 -            }
 -        }
 -    }
 -
 -    @Override
 -    public String toString() {
 -        try {
 -            StringBuilder buf = new StringBuilder();
 -            buf.append("<dubbo:");
 -            buf.append(getTagName(getClass()));
 -            Method[] methods = getClass().getMethods();
 -            for (Method method : methods) {
 -                try {
 -                    String name = method.getName();
 -                    if ((name.startsWith("get") || name.startsWith("is"))
 -                            && !"get".equals(name) && !"is".equals(name)
 -                            && !"getClass".equals(name) && 
!"getObject".equals(name)
 -                            && Modifier.isPublic(method.getModifiers())
 -                            && method.getParameterTypes().length == 0
 -                            && isPrimitive(method.getReturnType())) {
 -                        int i = name.startsWith("get") ? 3 : 2;
 -                        String key = name.substring(i, i + 1).toLowerCase() + 
name.substring(i + 1);
 -                        Object value = method.invoke(this);
 -                        if (value != null) {
 -                            buf.append(" ");
 -                            buf.append(key);
 -                            buf.append("=\"");
 -                            buf.append(value);
 -                            buf.append("\"");
 -                        }
 -                    }
 -                } catch (Exception e) {
 -                    logger.warn(e.getMessage(), e);
 -                }
 -            }
 -            buf.append(" />");
 -            return buf.toString();
 -        } catch (Throwable t) {
 -            logger.warn(t.getMessage(), t);
 -            return super.toString();
 -        }
 -    }
 -
 -}
 +/*
 + * 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.config.CompositeConfiguration;
 +import org.apache.dubbo.common.config.Configuration;
 +import org.apache.dubbo.common.extension.ExtensionLoader;
 +import org.apache.dubbo.common.logger.Logger;
 +import org.apache.dubbo.common.logger.LoggerFactory;
 +import org.apache.dubbo.common.utils.CollectionUtils;
 +import org.apache.dubbo.common.utils.ReflectUtils;
 +import org.apache.dubbo.common.utils.StringUtils;
 +import org.apache.dubbo.config.context.Environment;
 +import org.apache.dubbo.config.support.Parameter;
 +import org.apache.dubbo.config.utils.ConfigConverter;
 +import org.apache.dubbo.rpc.model.ConsumerMethodModel;
 +
 +import java.io.Serializable;
 +import java.lang.reflect.Method;
 +import java.lang.reflect.Modifier;
 +import java.util.HashMap;
 +import java.util.Map;
 +import java.util.regex.Matcher;
 +import java.util.regex.Pattern;
 +
 +/**
 + * Utility methods and public methods for parsing configuration
 + *
 + * @export
 + */
 +public abstract class AbstractConfig implements Serializable {
 +
 +    protected static final Logger logger = 
LoggerFactory.getLogger(AbstractConfig.class);
 +    private static final long serialVersionUID = 4267533505537413570L;
 +    private static final int MAX_LENGTH = 200;
 +
 +    private static final int MAX_PATH_LENGTH = 200;
 +
 +    private static final Pattern PATTERN_NAME = 
Pattern.compile("[\\-._0-9a-zA-Z]+");
 +
 +    private static final Pattern PATTERN_MULTI_NAME = 
Pattern.compile("[,\\-._0-9a-zA-Z]+");
 +
 +    private static final Pattern PATTERN_METHOD_NAME = 
Pattern.compile("[a-zA-Z][0-9a-zA-Z]*");
 +
 +    private static final Pattern PATTERN_PATH = 
Pattern.compile("[/\\-$._0-9a-zA-Z]+");
 +
-     private static final Pattern PATTERN_NAME_HAS_SYMBOL = 
Pattern.compile("[:*,/\\-._0-9a-zA-Z]+");
++    private static final Pattern PATTERN_NAME_HAS_SYMBOL = 
Pattern.compile("[:*,\\s/\\-._0-9a-zA-Z]+");
 +
 +    private static final Pattern PATTERN_KEY = 
Pattern.compile("[*,\\-._0-9a-zA-Z]+");
 +    private static final Map<String, String> legacyProperties = new 
HashMap<String, String>();
 +    private static final String[] SUFFIXES = new String[]{"Config", "Bean"};
 +
 +    private boolean init;
 +    private volatile Map<String, String> metaData;
 +
 +    static {
 +        legacyProperties.put("dubbo.protocol.name", "dubbo.service.protocol");
 +        legacyProperties.put("dubbo.protocol.host", 
"dubbo.service.server.host");
 +        legacyProperties.put("dubbo.protocol.port", 
"dubbo.service.server.port");
 +        legacyProperties.put("dubbo.protocol.threads", 
"dubbo.service.max.thread.pool.size");
 +        legacyProperties.put("dubbo.consumer.timeout", 
"dubbo.service.invoke.timeout");
 +        legacyProperties.put("dubbo.consumer.retries", 
"dubbo.service.max.retry.providers");
 +        legacyProperties.put("dubbo.consumer.check", 
"dubbo.service.allow.no.provider");
 +        legacyProperties.put("dubbo.service.url", "dubbo.service.address");
 +    }
 +
 +    protected String id;
 +
 +    private static String convertLegacyValue(String key, String value) {
 +        if (value != null && value.length() > 0) {
 +            if ("dubbo.service.max.retry.providers".equals(key)) {
 +                return String.valueOf(Integer.parseInt(value) - 1);
 +            } else if ("dubbo.service.allow.no.provider".equals(key)) {
 +                return String.valueOf(!Boolean.parseBoolean(value));
 +            }
 +        }
 +        return value;
 +    }
 +
 +    private static String getTagName(Class<?> cls) {
 +        String tag = cls.getSimpleName();
 +        for (String suffix : SUFFIXES) {
 +            if (tag.endsWith(suffix)) {
 +                tag = tag.substring(0, tag.length() - suffix.length());
 +                break;
 +            }
 +        }
 +        tag = tag.toLowerCase();
 +        return tag;
 +    }
 +
 +    protected static void appendParameters(Map<String, String> parameters, 
Object config) {
 +        appendParameters(parameters, config, null);
 +    }
 +
 +    @SuppressWarnings("unchecked")
 +    protected static void appendParameters(Map<String, String> parameters, 
Object config, String prefix) {
 +        if (config == null) {
 +            return;
 +        }
 +        Method[] methods = config.getClass().getMethods();
 +        for (Method method : methods) {
 +            try {
 +                String name = method.getName();
 +                if ((name.startsWith("get") || name.startsWith("is"))
 +                        && !"getClass".equals(name)
 +                        && Modifier.isPublic(method.getModifiers())
 +                        && method.getParameterTypes().length == 0
 +                        && isPrimitive(method.getReturnType())) {
 +                    Parameter parameter = 
method.getAnnotation(Parameter.class);
 +                    if (method.getReturnType() == Object.class || parameter 
!= null && parameter.excluded()) {
 +                        continue;
 +                    }
 +                    int i = name.startsWith("get") ? 3 : 2;
 +                    String prop = 
StringUtils.camelToSplitName(name.substring(i, i + 1).toLowerCase() + 
name.substring(i + 1), ".");
 +                    String key;
 +                    if (parameter != null && parameter.key().length() > 0) {
 +                        key = parameter.key();
 +                    } else {
 +                        key = prop;
 +                    }
 +                    Object value = method.invoke(config);
 +                    String str = String.valueOf(value).trim();
 +                    if (value != null && str.length() > 0) {
 +                        if (parameter != null && parameter.escaped()) {
 +                            str = URL.encode(str);
 +                        }
 +                        if (parameter != null && parameter.append()) {
 +                            String pre = parameters.get(Constants.DEFAULT_KEY 
+ "." + key);
 +                            if (pre != null && pre.length() > 0) {
 +                                str = pre + "," + str;
 +                            }
 +                            pre = parameters.get(key);
 +                            if (pre != null && pre.length() > 0) {
 +                                str = pre + "," + str;
 +                            }
 +                        }
 +                        if (prefix != null && prefix.length() > 0) {
 +                            key = prefix + "." + key;
 +                        }
 +                        parameters.put(key, str);
 +                    } else if (parameter != null && parameter.required()) {
 +                        throw new 
IllegalStateException(config.getClass().getSimpleName() + "." + key + " == 
null");
 +                    }
 +                } else if ("getParameters".equals(name)
 +                        && Modifier.isPublic(method.getModifiers())
 +                        && method.getParameterTypes().length == 0
 +                        && method.getReturnType() == Map.class) {
 +                    Map<String, String> map = (Map<String, String>) 
method.invoke(config, new Object[0]);
 +                    if (map != null && map.size() > 0) {
 +                        String pre = (prefix != null && prefix.length() > 0 ? 
prefix + "." : "");
 +                        for (Map.Entry<String, String> entry : 
map.entrySet()) {
 +                            parameters.put(pre + entry.getKey().replace('-', 
'.'), entry.getValue());
 +                        }
 +                    }
 +                }
 +            } catch (Exception e) {
 +                throw new IllegalStateException(e.getMessage(), e);
 +            }
 +        }
 +    }
 +
 +    protected static void appendAttributes(Map<String, Object> parameters, 
Object config) {
 +        appendAttributes(parameters, config, null);
 +    }
 +
 +    protected static void appendAttributes(Map<String, Object> parameters, 
Object config, String prefix) {
 +        if (config == null) {
 +            return;
 +        }
 +        Method[] methods = config.getClass().getMethods();
 +        for (Method method : methods) {
 +            try {
 +                Parameter parameter = method.getAnnotation(Parameter.class);
 +                if (parameter == null || !parameter.attribute()) {
 +                    continue;
 +                }
 +                String name = method.getName();
 +                if ((name.startsWith("get") || name.startsWith("is"))
 +                        && !"getClass".equals(name)
 +                        && Modifier.isPublic(method.getModifiers())
 +                        && method.getParameterTypes().length == 0
 +                        && isPrimitive(method.getReturnType())) {
 +                    String key;
 +                    if (parameter.key().length() > 0) {
 +                        key = parameter.key();
 +                    } else {
 +                        int i = name.startsWith("get") ? 3 : 2;
 +                        key = name.substring(i, i + 1).toLowerCase() + 
name.substring(i + 1);
 +                    }
 +                    Object value = method.invoke(config);
 +                    if (value != null) {
 +                        if (prefix != null && prefix.length() > 0) {
 +                            key = prefix + "." + key;
 +                        }
 +                        parameters.put(key, value);
 +                    }
 +                }
 +            } catch (Exception e) {
 +                throw new IllegalStateException(e.getMessage(), e);
 +            }
 +        }
 +    }
 +
 +    protected static ConsumerMethodModel.AsyncMethodInfo 
convertMethodConfig2AyncInfo(MethodConfig methodConfig) {
 +        if (methodConfig == null || (methodConfig.getOninvoke() == null && 
methodConfig.getOnreturn() == null && methodConfig.getOnthrow() == null)) {
 +            return null;
 +        }
 +
 +        //check config conflict
 +        if (Boolean.FALSE.equals(methodConfig.isReturn()) && 
(methodConfig.getOnreturn() != null || methodConfig.getOnthrow() != null)) {
 +            throw new IllegalStateException("method config error : return 
attribute must be set true when onreturn or onthrow has been set.");
 +        }
 +
 +        ConsumerMethodModel.AsyncMethodInfo asyncMethodInfo = new 
ConsumerMethodModel.AsyncMethodInfo();
 +
 +        asyncMethodInfo.setOninvokeInstance(methodConfig.getOninvoke());
 +        asyncMethodInfo.setOnreturnInstance(methodConfig.getOnreturn());
 +        asyncMethodInfo.setOnthrowInstance(methodConfig.getOnthrow());
 +
 +        try {
 +            String oninvokeMethod = methodConfig.getOninvokeMethod();
 +            if (StringUtils.isNotEmpty(oninvokeMethod)) {
 +                
asyncMethodInfo.setOninvokeMethod(getMethodByName(methodConfig.getOninvoke().getClass(),
 oninvokeMethod));
 +            }
 +
 +            String onreturnMethod = methodConfig.getOnreturnMethod();
 +            if (StringUtils.isNotEmpty(onreturnMethod)) {
 +                
asyncMethodInfo.setOnreturnMethod(getMethodByName(methodConfig.getOnreturn().getClass(),
 onreturnMethod));
 +            }
 +
 +            String onthrowMethod = methodConfig.getOnthrowMethod();
 +            if (StringUtils.isNotEmpty(onthrowMethod)) {
 +                
asyncMethodInfo.setOnthrowMethod(getMethodByName(methodConfig.getOnthrow().getClass(),
 onthrowMethod));
 +            }
 +        } catch (Exception e) {
 +            throw new IllegalStateException(e.getMessage(), e);
 +        }
 +
 +        return asyncMethodInfo;
 +    }
 +
 +    private static Method getMethodByName(Class<?> clazz, String methodName) {
 +        try {
 +            return ReflectUtils.findMethodByMethodName(clazz, methodName);
 +        } catch (Exception e) {
 +            throw new IllegalStateException(e);
 +        }
 +    }
 +
 +    private static boolean isPrimitive(Class<?> type) {
 +        return type.isPrimitive()
 +                || type == String.class
 +                || type == Character.class
 +                || type == Boolean.class
 +                || type == Byte.class
 +                || type == Short.class
 +                || type == Integer.class
 +                || type == Long.class
 +                || type == Float.class
 +                || type == Double.class
 +                || type == Object.class;
 +    }
 +
 +    private static Object convertPrimitive(Class<?> type, String value) {
 +        if (type == char.class || type == Character.class) {
 +            return value.length() > 0 ? value.charAt(0) : '\0';
 +        } else if (type == boolean.class || type == Boolean.class) {
 +            return Boolean.valueOf(value);
 +        } else if (type == byte.class || type == Byte.class) {
 +            return Byte.valueOf(value);
 +        } else if (type == short.class || type == Short.class) {
 +            return Short.valueOf(value);
 +        } else if (type == int.class || type == Integer.class) {
 +            return Integer.valueOf(value);
 +        } else if (type == long.class || type == Long.class) {
 +            return Long.valueOf(value);
 +        } else if (type == float.class || type == Float.class) {
 +            return Float.valueOf(value);
 +        } else if (type == double.class || type == Double.class) {
 +            return Double.valueOf(value);
 +        }
 +        return value;
 +    }
 +
 +    protected static void checkExtension(Class<?> type, String property, 
String value) {
 +        checkName(property, value);
 +        if (value != null && value.length() > 0
 +                && 
!ExtensionLoader.getExtensionLoader(type).hasExtension(value)) {
 +            throw new IllegalStateException("No such extension " + value + " 
for " + property + "/" + type.getName());
 +        }
 +    }
 +
 +    protected static void checkMultiExtension(Class<?> type, String property, 
String value) {
 +        checkMultiName(property, value);
 +        if (value != null && value.length() > 0) {
 +            String[] values = value.split("\\s*[,]+\\s*");
 +            for (String v : values) {
 +                if (v.startsWith(Constants.REMOVE_VALUE_PREFIX)) {
 +                    v = v.substring(1);
 +                }
 +                if (Constants.DEFAULT_KEY.equals(v)) {
 +                    continue;
 +                }
 +                if 
(!ExtensionLoader.getExtensionLoader(type).hasExtension(v)) {
 +                    throw new IllegalStateException("No such extension " + v 
+ " for " + property + "/" + type.getName());
 +                }
 +            }
 +        }
 +    }
 +
 +    protected static void checkLength(String property, String value) {
 +        checkProperty(property, value, MAX_LENGTH, null);
 +    }
 +
 +    protected static void checkPathLength(String property, String value) {
 +        checkProperty(property, value, MAX_PATH_LENGTH, null);
 +    }
 +
 +    protected static void checkName(String property, String value) {
 +        checkProperty(property, value, MAX_LENGTH, PATTERN_NAME);
 +    }
 +
 +    protected static void checkNameHasSymbol(String property, String value) {
 +        checkProperty(property, value, MAX_LENGTH, PATTERN_NAME_HAS_SYMBOL);
 +    }
 +
 +    protected static void checkKey(String property, String value) {
 +        checkProperty(property, value, MAX_LENGTH, PATTERN_KEY);
 +    }
 +
 +    protected static void checkMultiName(String property, String value) {
 +        checkProperty(property, value, MAX_LENGTH, PATTERN_MULTI_NAME);
 +    }
 +
 +    protected static void checkPathName(String property, String value) {
 +        checkProperty(property, value, MAX_PATH_LENGTH, PATTERN_PATH);
 +    }
 +
 +    protected static void checkMethodName(String property, String value) {
 +        checkProperty(property, value, MAX_LENGTH, PATTERN_METHOD_NAME);
 +    }
 +
 +    protected static void checkParameterName(Map<String, String> parameters) {
 +        if (parameters == null || parameters.size() == 0) {
 +            return;
 +        }
 +        for (Map.Entry<String, String> entry : parameters.entrySet()) {
 +            checkNameHasSymbol(entry.getKey(), entry.getValue());
 +        }
 +    }
 +
 +    protected static void checkProperty(String property, String value, int 
maxlength, Pattern pattern) {
 +        if (value == null || value.length() == 0) {
 +            return;
 +        }
 +        if (value.length() > maxlength) {
 +            throw new IllegalStateException("Invalid " + property + "=\"" + 
value + "\" is longer than " + maxlength);
 +        }
 +        if (pattern != null) {
 +            Matcher matcher = pattern.matcher(value);
 +            if (!matcher.matches()) {
 +                throw new IllegalStateException("Invalid " + property + "=\"" 
+ value + "\" contains illegal " +
 +                        "character, only digit, letter, '-', '_' or '.' is 
legal.");
 +            }
 +        }
 +    }
 +
 +    @Parameter(excluded = true)
 +    public String getId() {
 +        return id;
 +    }
 +
 +    public void setId(String id) {
 +        this.id = id;
 +    }
 +
 +    protected void appendAnnotation(Class<?> annotationClass, Object 
annotation) {
 +        Method[] methods = annotationClass.getMethods();
 +        for (Method method : methods) {
 +            if (method.getDeclaringClass() != Object.class
 +                    && method.getReturnType() != void.class
 +                    && method.getParameterTypes().length == 0
 +                    && Modifier.isPublic(method.getModifiers())
 +                    && !Modifier.isStatic(method.getModifiers())) {
 +                try {
 +                    String property = method.getName();
 +                    if ("interfaceClass".equals(property) || 
"interfaceName".equals(property)) {
 +                        property = "interface";
 +                    }
 +                    String setter = "set" + property.substring(0, 
1).toUpperCase() + property.substring(1);
 +                    Object value = method.invoke(annotation);
 +                    if (value != null && 
!value.equals(method.getDefaultValue())) {
 +                        Class<?> parameterType = 
ReflectUtils.getBoxedClass(method.getReturnType());
 +                        if ("filter".equals(property) || 
"listener".equals(property)) {
 +                            parameterType = String.class;
 +                            value = StringUtils.join((String[]) value, ",");
 +                        } else if ("parameters".equals(property)) {
 +                            parameterType = Map.class;
 +                            value = CollectionUtils.toStringMap((String[]) 
value);
 +                        }
 +                        try {
 +                            Method setterMethod = 
getClass().getMethod(setter, parameterType);
 +                            setterMethod.invoke(this, value);
 +                        } catch (NoSuchMethodException e) {
 +                            // ignore
 +                        }
 +                    }
 +                } catch (Throwable e) {
 +                    logger.error(e.getMessage(), e);
 +                }
 +            }
 +        }
 +    }
 +
 +
 +    /**
 +     * Should be called after Config was fully initialized.
 +     *
 +     * @return
 +     */
 +    public Map<String, String> getMetaData() {
 +        metaData = new HashMap<>();
 +        Method[] methods = this.getClass().getMethods();
 +        for (Method method : methods) {
 +            try {
 +                String name = method.getName();
 +                if ((name.startsWith("get") || name.startsWith("is"))
 +                        && !name.equals("get")
 +                        && !"getClass".equals(name)
 +                        && Modifier.isPublic(method.getModifiers())
 +                        && method.getParameterTypes().length == 0
 +                        && isPrimitive(method.getReturnType())) {
 +                    int i = name.startsWith("get") ? 3 : 2;
 +                    String prop = 
StringUtils.camelToSplitName(name.substring(i, i + 1).toLowerCase() + 
name.substring(i + 1), ".");
 +                    String key;
 +                    Parameter parameter = 
method.getAnnotation(Parameter.class);
 +                    if (parameter != null && parameter.key().length() > 0) {
 +                        key = parameter.key();
 +                    } else {
 +                        key = prop;
 +                    }
 +                    if (method.getReturnType() == Object.class || parameter 
!= null && parameter.excluded()) {
 +                        metaData.put(key, null);
 +                        continue;
 +                    }
 +                    Object value = method.invoke(this);
 +                    String str = String.valueOf(value).trim();
 +                    if (value != null && str.length() > 0) {
 +                        if (parameter != null && parameter.escaped()) {
 +                            str = URL.encode(str);
 +                        }
 +                        if (parameter != null && parameter.append()) {
 +                            String pre = 
String.valueOf(metaData.get(Constants.DEFAULT_KEY + "." + key));
 +                            if (pre != null && pre.length() > 0) {
 +                                str = pre + "," + str;
 +                            }
 +                            pre = String.valueOf(metaData.get(key));
 +                            if (pre != null && pre.length() > 0) {
 +                                str = pre + "," + str;
 +                            }
 +                        }
 +                      /*  if (prefix != null && prefix.length() > 0) {
 +                            key = prefix + "." + key;
 +                        }*/
 +                        metaData.put(key, str);
 +                    } else {
 +                        metaData.put(key, null);
 +                    }
 +                    // TODO check required somewhere else.
 +                    /*else if (parameter != null && parameter.required()) {
 +                        throw new 
IllegalStateException(this.getClass().getSimpleName() + "." + key + " == null");
 +                    }*/
 +                } else if ("getParameters".equals(name)
 +                        && Modifier.isPublic(method.getModifiers())
 +                        && method.getParameterTypes().length == 0
 +                        && method.getReturnType() == Map.class) {
 +                    Map<String, String> map = (Map<String, String>) 
method.invoke(this, new Object[0]);
 +                    if (map != null && map.size() > 0) {
 +//                            String pre = (prefix != null && prefix.length() 
> 0 ? prefix + "." : "");
 +                        for (Map.Entry<String, String> entry : 
map.entrySet()) {
 +                            metaData.put(entry.getKey().replace('-', '.'), 
entry.getValue());
 +                        }
 +                    }
 +                }
 +            } catch (Exception e) {
 +                System.out.println(this.getClass().getName());
 +                System.out.println(method.getName());
 +                throw new IllegalStateException(e.getMessage(), e);
 +            }
 +        }
 +        return metaData;
 +    }
 +
 +    @Parameter(excluded = true)
 +    public String getPrefix() {
 +        return Constants.DUBBO + "." + getTagName(this.getClass());
 +    }
 +
 +    /**
 +     * TODO
 +     * Currently, only support overriding of properties explicitly defined in 
Config class, doesn't support overriding of customized parameters stored in 
'parameters'.
 +     */
 +    public void refresh() {
 +        if (init) {
 +            return;
 +        }
 +        init = true;
 +
 +        try {
 +            Configuration configuration = 
ConfigConverter.toConfiguration(this);
 +            CompositeConfiguration compositeConfiguration = 
Environment.getInstance().getStartupCompositeConf(getPrefix(), getId());
 +            int index = 3;
 +            if (!Environment.getInstance().isConfigCenterFirst()) {
 +                index = 1;
 +            }
 +            compositeConfiguration.addConfiguration(index, configuration);
 +            // loop methods, get override value and set the new value back to 
method
 +            Method[] methods = getClass().getMethods();
 +            for (Method method : methods) {
 +                if (isSetter(method)) {
 +                    try {
 +                        String value = 
compositeConfiguration.getString(extractPropertyName(method));
 +                        if (value != null) {
 +                            method.invoke(this, 
convertPrimitive(method.getParameterTypes()[0], value));
 +                        }
 +                    } catch (NoSuchMethodException e) {
 +                        logger.warn("Failed to override the property " + 
method.getName() + " in " + this.getClass().getSimpleName() + ", please make 
sure every property has a getter/setter pair.", e);
 +                    }
 +                }
 +            }
 +        } catch (Exception e) {
 +            logger.error("Failed to override ", e);
 +        }
 +    }
 +
 +    private static boolean isSetter(Method method) {
 +        if (method.getName().startsWith("set")
 +                && !"set".equals(method.getName())
 +                && Modifier.isPublic(method.getModifiers())
 +                && method.getParameterCount() == 1
 +                && isPrimitive(method.getParameterTypes()[0])) {
 +            return true;
 +        }
 +        return false;
 +    }
 +
 +    public String extractPropertyName(Method setter) throws Exception {
 +        String propertyName = setter.getName().substring("set".length());
 +        Method getter = null;
 +        try {
 +            getter = getClass().getMethod("get" + propertyName);
 +        } catch (NoSuchMethodException e) {
 +            getter = getClass().getMethod("is" + propertyName);
 +        }
 +        Parameter parameter = getter.getAnnotation(Parameter.class);
 +        if (parameter != null && StringUtils.isNotEmpty(parameter.key()) && 
parameter.propertyKey()) {
 +            propertyName = parameter.key();
 +        } else {
 +            propertyName = propertyName.toLowerCase();
 +        }
 +        return propertyName;
 +    }
 +
 +    @Override
 +    public String toString() {
 +        try {
 +            StringBuilder buf = new StringBuilder();
 +            buf.append("<dubbo:");
 +            buf.append(getTagName(getClass()));
 +            Method[] methods = getClass().getMethods();
 +            for (Method method : methods) {
 +                try {
 +                    String name = method.getName();
 +                    if ((name.startsWith("get") || name.startsWith("is"))
-                             && !"getClass".equals(name) && 
!"get".equals(name) && !"is".equals(name)
++                            && !"get".equals(name) && !"is".equals(name)
++                            && !"getClass".equals(name) && 
!"getObject".equals(name)
 +                            && Modifier.isPublic(method.getModifiers())
 +                            && method.getParameterTypes().length == 0
 +                            && isPrimitive(method.getReturnType())) {
 +                        int i = name.startsWith("get") ? 3 : 2;
 +                        String key = name.substring(i, i + 1).toLowerCase() + 
name.substring(i + 1);
 +                        Object value = method.invoke(this);
 +                        if (value != null) {
 +                            buf.append(" ");
 +                            buf.append(key);
 +                            buf.append("=\"");
 +                            buf.append(value);
 +                            buf.append("\"");
 +                        }
 +                    }
 +                } catch (Exception e) {
 +                    logger.warn(e.getMessage(), e);
 +                }
 +            }
 +            buf.append(" />");
 +            return buf.toString();
 +        } catch (Throwable t) {
 +            logger.warn(t.getMessage(), t);
 +            return super.toString();
 +        }
 +    }
 +
 +    /**
 +     * FIXME check @Parameter(required=true) and any conditions that need to 
match.
 +     */
 +    @Parameter(excluded = true)
 +    public boolean isValid() {
 +        return true;
 +    }
 +
 +}
diff --cc 
dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ProtocolConfig.java
index 7e45e4c,7582169..3e9fdcd
--- 
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
@@@ -471,9 -470,4 +471,9 @@@ public class ProtocolConfig extends Abs
              
ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(name).destroy();
          }
      }
 +
 +    @Override
 +    public boolean isValid() {
 +        return StringUtils.isNotEmpty(name);
 +    }
- }
+ }
diff --cc 
dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
index f98d8c1,c39f3b6..2512839
--- 
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
@@@ -218,45 -244,8 +218,46 @@@ public class ReferenceConfig<T> extend
              }
          }
          checkApplication();
 +        checkMetadataReport();
 +        checkRegistryDataConfig();
 +    }
 +
 +    public synchronized T get() {
 +        checkAndUpdateSubConfigs();
 +
 +        if (destroyed) {
 +            throw new IllegalStateException("Already destroyed!");
 +        }
 +        if (ref == null) {
 +            init();
 +        }
 +        return ref;
 +    }
 +
 +    public synchronized void destroy() {
 +        if (ref == null) {
 +            return;
 +        }
 +        if (destroyed) {
 +            return;
 +        }
 +        destroyed = true;
 +        try {
 +            invoker.destroy();
 +        } catch (Throwable t) {
 +            logger.warn("Unexpected err when destroy invoker of 
ReferenceConfig(" + url + ").", t);
 +        }
 +        invoker = null;
 +        ref = null;
 +    }
 +
 +    private void init() {
 +        if (initialized) {
 +            return;
 +        }
 +        initialized = true;
-         checkStubAndMock(interfaceClass);
+         checkStub(interfaceClass);
+         checkMock(interfaceClass);
          Map<String, String> map = new HashMap<String, String>();
          resolveAsyncInterface(interfaceClass, map);
  
diff --cc 
dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
index 394a8f6,66e8d7f..0133b01
--- 
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
@@@ -284,45 -305,12 +284,46 @@@ public class ServiceConfig<T> extends A
                  throw new IllegalStateException("The stub implementation 
class " + stubClass.getName() + " not implement interface " + interfaceName);
              }
          }
-         checkStubAndMock(interfaceClass);
 -        checkApplication();
 -        checkRegistry();
 -        checkProtocol();
 -        appendProperties(this);
+         checkStub(interfaceClass);
+         checkMock(interfaceClass);
 +    }
 +
 +    public synchronized void export() {
 +        checkAndUpdateSubConfigs();
 +
 +        if (provider != null) {
 +            if (export == null) {
 +                export = provider.getExport();
 +            }
 +            if (delay == null) {
 +                delay = provider.getDelay();
 +            }
 +        }
 +        if (export != null && !export) {
 +            return;
 +        }
 +
 +        if (delay != null && delay > 0) {
 +            delayExportExecutor.schedule(new Runnable() {
 +                @Override
 +                public void run() {
 +                    doExport();
 +                }
 +            }, delay, TimeUnit.MILLISECONDS);
 +        } else {
 +            doExport();
 +        }
 +    }
 +
 +    protected synchronized void doExport() {
 +        if (unexported) {
 +            throw new IllegalStateException("Already unexported!");
 +        }
 +        if (exported) {
 +            return;
 +        }
 +        exported = true;
 +
          if (path == null || path.length() == 0) {
              path = interfaceName;
          }
diff --cc 
dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandler.java
index df0415b,035c3f9..afbc26b
--- 
a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandler.java
+++ 
b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandler.java
@@@ -24,9 -24,9 +24,10 @@@ import org.apache.dubbo.config.MonitorC
  import org.apache.dubbo.config.ProtocolConfig;
  import org.apache.dubbo.config.ProviderConfig;
  import org.apache.dubbo.config.RegistryConfig;
 +import org.apache.dubbo.config.spring.ConfigCenterBean;
  import org.apache.dubbo.config.spring.ReferenceBean;
  import org.apache.dubbo.config.spring.ServiceBean;
+ 
  import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
  
  /**

Reply via email to