You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2018/11/15 07:16:40 UTC
[incubator-dubbo] 01/04: Merge branch 'master' into dev-metadata
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 <ke...@gmail.com>
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;
/**