You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by me...@apache.org on 2018/03/30 15:33:55 UTC
[incubator-dubbo] branch 2.5.x updated: Polish alibaba/dubbo#1306
This is an automated email from the ASF dual-hosted git repository.
mercyblitz pushed a commit to branch 2.5.x
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo.git
The following commit(s) were added to refs/heads/2.5.x by this push:
new 1e5b28f Polish alibaba/dubbo#1306
1e5b28f is described below
commit 1e5b28f458ee5bb9ea3cb656fc5932e1296b3ee4
Author: mercyblitz <me...@gmail.com>
AuthorDate: Fri Mar 30 23:33:37 2018 +0800
Polish alibaba/dubbo#1306
---
.../AnnotationPropertyValuesAdapter.java | 92 ++++++++++++
.../DubboConfigBindingBeanPostProcessor.java | 115 ++++++++++++---
.../ReferenceAnnotationBeanPostProcessor.java | 161 +++++++++++++++++----
.../factory/annotation/ReferenceBeanBuilder.java | 26 +++-
.../ServiceAnnotationBeanPostProcessor.java | 49 +++----
.../annotation/DubboConfigBindingRegistrar.java | 64 +++-----
.../properties/AbstractDubboConfigBinder.java | 69 +++++++++
.../properties/DefaultDubboConfigBinder.java | 46 ++++++
.../context/properties/DubboConfigBinder.java | 58 ++++++++
.../converter/StringArrayToMapConverter.java} | 75 +++++-----
.../converter/StringArrayToStringConverter.java} | 74 +++++-----
.../dubbo/config/spring/util/AnnotationUtils.java | 89 ++++++++++++
.../dubbo/config/spring/util/ObjectUtils.java} | 74 +++++-----
.../config/spring/util/PropertySourcesUtils.java | 18 ++-
.../annotation/provider/AnnotationServiceImpl.java | 2 +-
.../AnnotationPropertyValuesAdapterTest.java | 158 ++++++++++++++++++++
.../DubboConfigBindingBeanPostProcessorTest.java | 66 +++++++++
.../ReferenceAnnotationBeanPostProcessorTest.java | 95 ++++++++++--
.../ServiceAnnotationBeanPostProcessorTest.java | 3 +-
.../properties/DefaultDubboConfigBinderTest.java | 56 +++++++
.../converter/StringArrayToMapConverterTest.java} | 89 +++++++-----
.../StringArrayToStringConverterTest.java} | 83 ++++++-----
22 files changed, 1241 insertions(+), 321 deletions(-)
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java
new file mode 100644
index 0000000..751399f
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java
@@ -0,0 +1,92 @@
+/*
+ * 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 com.alibaba.dubbo.config.spring.beans.factory.annotation;
+
+import org.springframework.beans.MutablePropertyValues;
+import org.springframework.beans.PropertyValue;
+import org.springframework.beans.PropertyValues;
+import org.springframework.core.env.PropertyResolver;
+
+import java.lang.annotation.Annotation;
+
+import static com.alibaba.dubbo.config.spring.util.AnnotationUtils.getAttributes;
+
+/**
+ * {@link Annotation} {@link PropertyValues} Adapter
+ *
+ * @see Annotation
+ * @see PropertyValues
+ * @since 2.5.11
+ */
+class AnnotationPropertyValuesAdapter implements PropertyValues {
+
+ private final Annotation annotation;
+
+ private final PropertyResolver propertyResolver;
+
+ private final boolean ignoreDefaultValue;
+
+ private final PropertyValues delegate;
+
+ public AnnotationPropertyValuesAdapter(Annotation annotation, PropertyResolver propertyResolver, boolean ignoreDefaultValue, String... ignoreAttributeNames) {
+ this.annotation = annotation;
+ this.propertyResolver = propertyResolver;
+ this.ignoreDefaultValue = ignoreDefaultValue;
+ this.delegate = adapt(annotation, ignoreDefaultValue, ignoreAttributeNames);
+ }
+
+ public AnnotationPropertyValuesAdapter(Annotation annotation, PropertyResolver propertyResolver, String... ignoreAttributeNames) {
+ this(annotation, propertyResolver, true, ignoreAttributeNames);
+ }
+
+ private PropertyValues adapt(Annotation annotation, boolean ignoreDefaultValue, String... ignoreAttributeNames) {
+ return new MutablePropertyValues(getAttributes(annotation, propertyResolver, ignoreDefaultValue, ignoreAttributeNames));
+ }
+
+ public Annotation getAnnotation() {
+ return annotation;
+ }
+
+ public boolean isIgnoreDefaultValue() {
+ return ignoreDefaultValue;
+ }
+
+ @Override
+ public PropertyValue[] getPropertyValues() {
+ return delegate.getPropertyValues();
+ }
+
+ @Override
+ public PropertyValue getPropertyValue(String propertyName) {
+ return delegate.getPropertyValue(propertyName);
+ }
+
+ @Override
+ public PropertyValues changesSince(PropertyValues old) {
+ return delegate.changesSince(old);
+ }
+
+ @Override
+ public boolean contains(String propertyName) {
+ return delegate.contains(propertyName);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return delegate.isEmpty();
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/DubboConfigBindingBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/DubboConfigBindingBeanPostProcessor.java
index 6899ad4..6248ed3 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/DubboConfigBindingBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/DubboConfigBindingBeanPostProcessor.java
@@ -17,13 +17,25 @@
package com.alibaba.dubbo.config.spring.beans.factory.annotation;
import com.alibaba.dubbo.common.utils.Assert;
+import com.alibaba.dubbo.config.AbstractConfig;
import com.alibaba.dubbo.config.spring.context.annotation.DubboConfigBindingRegistrar;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubboConfigBinding;
+import com.alibaba.dubbo.config.spring.context.properties.DefaultDubboConfigBinder;
+import com.alibaba.dubbo.config.spring.context.properties.DubboConfigBinder;
+import com.alibaba.dubbo.config.spring.util.BeanFactoryUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.core.env.Environment;
import org.springframework.validation.DataBinder;
import java.util.Arrays;
@@ -35,43 +47,52 @@ import java.util.Arrays;
* @see DubboConfigBindingRegistrar
* @since 2.5.8
*/
-public class DubboConfigBindingBeanPostProcessor implements BeanPostProcessor {
+
+public class DubboConfigBindingBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware, InitializingBean {
private final Log log = LogFactory.getLog(getClass());
/**
- * Binding Bean Name
+ * The prefix of Configuration Properties
*/
- private final String beanName;
+ private final String prefix;
/**
- * Binding {@link PropertyValues}
+ * Binding Bean Name
*/
- private final PropertyValues propertyValues;
+ private final String beanName;
+ private DubboConfigBinder dubboConfigBinder;
+
+ private ApplicationContext applicationContext;
+
+ private boolean ignoreUnknownFields = true;
+
+ private boolean ignoreInvalidFields = true;
/**
- * @param beanName Binding Bean Name
- * @param propertyValues {@link PropertyValues}
+ * @param prefix the prefix of Configuration Properties
+ * @param beanName the binding Bean Name
*/
- public DubboConfigBindingBeanPostProcessor(String beanName, PropertyValues propertyValues) {
+ public DubboConfigBindingBeanPostProcessor(String prefix, String beanName) {
+ Assert.notNull(prefix, "The prefix of Configuration Properties must not be null");
Assert.notNull(beanName, "The name of bean must not be null");
- Assert.notNull(propertyValues, "The PropertyValues of bean must not be null");
+ this.prefix = prefix;
this.beanName = beanName;
- this.propertyValues = propertyValues;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- if (beanName.equals(this.beanName)) {
- DataBinder dataBinder = new DataBinder(bean);
- // TODO ignore invalid fields by annotation attribute
- dataBinder.setIgnoreInvalidFields(true);
- dataBinder.bind(propertyValues);
+ if (beanName.equals(this.beanName) && bean instanceof AbstractConfig) {
+
+ AbstractConfig dubboConfig = (AbstractConfig) bean;
+
+ dubboConfigBinder.bind(prefix, dubboConfig);
+
if (log.isInfoEnabled()) {
- log.info("The properties of bean [name : " + beanName + "] have been binding by values : "
- + Arrays.asList(propertyValues.getPropertyValues()));
+ log.info("The properties of bean [name : " + beanName + "] have been binding by prefix of " +
+ "configuration properties : " + prefix);
}
}
@@ -79,10 +100,70 @@ public class DubboConfigBindingBeanPostProcessor implements BeanPostProcessor {
}
+ public boolean isIgnoreUnknownFields() {
+ return ignoreUnknownFields;
+ }
+
+ public void setIgnoreUnknownFields(boolean ignoreUnknownFields) {
+ this.ignoreUnknownFields = ignoreUnknownFields;
+ }
+
+ public boolean isIgnoreInvalidFields() {
+ return ignoreInvalidFields;
+ }
+
+ public void setIgnoreInvalidFields(boolean ignoreInvalidFields) {
+ this.ignoreInvalidFields = ignoreInvalidFields;
+ }
+
+ public DubboConfigBinder getDubboConfigBinder() {
+ return dubboConfigBinder;
+ }
+
+ public void setDubboConfigBinder(DubboConfigBinder dubboConfigBinder) {
+ this.dubboConfigBinder = dubboConfigBinder;
+ }
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ this.applicationContext = applicationContext;
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+
+ if (dubboConfigBinder == null) {
+ try {
+ dubboConfigBinder = applicationContext.getBean(DubboConfigBinder.class);
+ } catch (BeansException ignored) {
+ if (log.isDebugEnabled()) {
+ log.debug("DubboConfigBinder Bean can't be found in ApplicationContext.");
+ }
+ // Use Default implementation
+ dubboConfigBinder = createDubboConfigBinder(applicationContext.getEnvironment());
+ }
+ }
+
+ dubboConfigBinder.setIgnoreUnknownFields(ignoreUnknownFields);
+ dubboConfigBinder.setIgnoreInvalidFields(ignoreInvalidFields);
+
+ }
+
+ /**
+ * Create {@link DubboConfigBinder} instance.
+ *
+ * @param environment
+ * @return {@link DefaultDubboConfigBinder}
+ */
+ protected DubboConfigBinder createDubboConfigBinder(Environment environment) {
+ DefaultDubboConfigBinder defaultDubboConfigBinder = new DefaultDubboConfigBinder();
+ defaultDubboConfigBinder.setEnvironment(environment);
+ return defaultDubboConfigBinder;
+ }
+
}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
index d8411de..31478f6 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
@@ -33,6 +33,7 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.PriorityOrdered;
+import org.springframework.core.env.Environment;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
@@ -41,9 +42,7 @@ import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
+import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -73,8 +72,8 @@ public class ReferenceAnnotationBeanPostProcessor extends InstantiationAwareBean
private ClassLoader classLoader;
- private final ConcurrentMap<String, InjectionMetadata> injectionMetadataCache =
- new ConcurrentHashMap<String, InjectionMetadata>(256);
+ private final ConcurrentMap<String, ReferenceInjectionMetadata> injectionMetadataCache =
+ new ConcurrentHashMap<String, ReferenceInjectionMetadata>(256);
private final ConcurrentMap<String, ReferenceBean<?>> referenceBeansCache =
new ConcurrentHashMap<String, ReferenceBean<?>>();
@@ -101,9 +100,9 @@ public class ReferenceAnnotationBeanPostProcessor extends InstantiationAwareBean
* @param beanClass The {@link Class} of Bean
* @return non-null {@link List}
*/
- private List<InjectionMetadata.InjectedElement> findFieldReferenceMetadata(final Class<?> beanClass) {
+ private List<ReferenceFieldElement> findFieldReferenceMetadata(final Class<?> beanClass) {
- final List<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
+ final List<ReferenceFieldElement> elements = new LinkedList<ReferenceFieldElement>();
ReflectionUtils.doWithFields(beanClass, new ReflectionUtils.FieldCallback() {
@Override
@@ -136,9 +135,9 @@ public class ReferenceAnnotationBeanPostProcessor extends InstantiationAwareBean
* @param beanClass The {@link Class} of Bean
* @return non-null {@link List}
*/
- private List<InjectionMetadata.InjectedElement> findMethodReferenceMetadata(final Class<?> beanClass) {
+ private List<ReferenceMethodElement> findMethodReferenceMetadata(final Class<?> beanClass) {
- final List<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
+ final List<ReferenceMethodElement> elements = new LinkedList<ReferenceMethodElement>();
ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {
@Override
@@ -180,15 +179,10 @@ public class ReferenceAnnotationBeanPostProcessor extends InstantiationAwareBean
* @param beanClass
* @return
*/
- private InjectionMetadata buildReferenceMetadata(final Class<?> beanClass) {
-
- final List<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
-
- elements.addAll(findFieldReferenceMetadata(beanClass));
-
- elements.addAll(findMethodReferenceMetadata(beanClass));
-
- return new InjectionMetadata(beanClass, elements);
+ private ReferenceInjectionMetadata buildReferenceMetadata(final Class<?> beanClass) {
+ Collection<ReferenceFieldElement> fieldElements = findFieldReferenceMetadata(beanClass);
+ Collection<ReferenceMethodElement> methodElements = findMethodReferenceMetadata(beanClass);
+ return new ReferenceInjectionMetadata(beanClass, fieldElements, methodElements);
}
@@ -196,7 +190,7 @@ public class ReferenceAnnotationBeanPostProcessor extends InstantiationAwareBean
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
- InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
+ ReferenceInjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
@@ -270,6 +264,43 @@ public class ReferenceAnnotationBeanPostProcessor extends InstantiationAwareBean
return this.referenceBeansCache.values();
}
+
+ /**
+ * {@link Reference} {@link InjectionMetadata} implementation
+ *
+ * @since 2.5.11
+ */
+ private static class ReferenceInjectionMetadata extends InjectionMetadata {
+
+ private final Collection<ReferenceFieldElement> fieldElements;
+
+ private final Collection<ReferenceMethodElement> methodElements;
+
+
+ public ReferenceInjectionMetadata(Class<?> targetClass, Collection<ReferenceFieldElement> fieldElements,
+ Collection<ReferenceMethodElement> methodElements) {
+ super(targetClass, combine(fieldElements, methodElements));
+ this.fieldElements = fieldElements;
+ this.methodElements = methodElements;
+ }
+
+ private static <T> Collection<T> combine(Collection<? extends T>... elements) {
+ List<T> allElements = new ArrayList<T>();
+ for (Collection<? extends T> e : elements) {
+ allElements.addAll(e);
+ }
+ return allElements;
+ }
+
+ public Collection<ReferenceFieldElement> getFieldElements() {
+ return fieldElements;
+ }
+
+ public Collection<ReferenceMethodElement> getMethodElements() {
+ return methodElements;
+ }
+ }
+
/**
* {@link Reference} {@link Method} {@link InjectionMetadata.InjectedElement}
*/
@@ -279,6 +310,8 @@ public class ReferenceAnnotationBeanPostProcessor extends InstantiationAwareBean
private final Reference reference;
+ private volatile ReferenceBean<?> referenceBean;
+
protected ReferenceMethodElement(Method method, PropertyDescriptor pd, Reference reference) {
super(method, pd);
this.method = method;
@@ -290,11 +323,11 @@ public class ReferenceAnnotationBeanPostProcessor extends InstantiationAwareBean
Class<?> referenceClass = pd.getPropertyType();
- Object referenceBean = buildReferenceBean(reference, referenceClass);
+ referenceBean = buildReferenceBean(reference, referenceClass);
ReflectionUtils.makeAccessible(method);
- method.invoke(bean, referenceBean);
+ method.invoke(bean, referenceBean.getObject());
}
@@ -309,6 +342,8 @@ public class ReferenceAnnotationBeanPostProcessor extends InstantiationAwareBean
private final Reference reference;
+ private volatile ReferenceBean<?> referenceBean;
+
protected ReferenceFieldElement(Field field, Reference reference) {
super(field, null);
this.field = field;
@@ -320,17 +355,17 @@ public class ReferenceAnnotationBeanPostProcessor extends InstantiationAwareBean
Class<?> referenceClass = field.getType();
- Object referenceBean = buildReferenceBean(reference, referenceClass);
+ referenceBean = buildReferenceBean(reference, referenceClass);
ReflectionUtils.makeAccessible(field);
- field.set(bean, referenceBean);
+ field.set(bean, referenceBean.getObject());
}
}
- private Object buildReferenceBean(Reference reference, Class<?> referenceClass) throws Exception {
+ private ReferenceBean<?> buildReferenceBean(Reference reference, Class<?> referenceClass) throws Exception {
String referenceBeanCacheKey = generateReferenceBeanCacheKey(reference, referenceClass);
@@ -348,8 +383,8 @@ public class ReferenceAnnotationBeanPostProcessor extends InstantiationAwareBean
}
+ return referenceBean;
- return referenceBean.get();
}
@@ -360,11 +395,17 @@ public class ReferenceAnnotationBeanPostProcessor extends InstantiationAwareBean
* @param beanClass {@link Class}
* @return
*/
- private static String generateReferenceBeanCacheKey(Reference reference, Class<?> beanClass) {
+ private String generateReferenceBeanCacheKey(Reference reference, Class<?> beanClass) {
String interfaceName = resolveInterfaceName(reference, beanClass);
- String key = reference.group() + "/" + interfaceName + ":" + reference.version();
+ String key = reference.url() + "/" + interfaceName +
+ "/" + reference.version() +
+ "/" + reference.group();
+
+ Environment environment = applicationContext.getEnvironment();
+
+ key = environment.resolvePlaceholders(key);
return key;
@@ -390,4 +431,70 @@ public class ReferenceAnnotationBeanPostProcessor extends InstantiationAwareBean
}
+
+ /**
+ * Get {@link ReferenceBean} {@link Map} in injected field.
+ *
+ * @return non-null {@link Map}
+ * @since 2.5.11
+ */
+ public Map<InjectionMetadata.InjectedElement, ReferenceBean<?>> getInjectedFieldReferenceBeanMap() {
+
+ Map<InjectionMetadata.InjectedElement, ReferenceBean<?>> injectedElementReferenceBeanMap =
+ new LinkedHashMap<InjectionMetadata.InjectedElement, ReferenceBean<?>>();
+
+ for (ReferenceInjectionMetadata metadata : injectionMetadataCache.values()) {
+
+ Collection<ReferenceFieldElement> fieldElements = metadata.getFieldElements();
+
+ for (ReferenceFieldElement fieldElement : fieldElements) {
+
+ injectedElementReferenceBeanMap.put(fieldElement, fieldElement.referenceBean);
+
+ }
+
+ }
+
+ return injectedElementReferenceBeanMap;
+
+ }
+
+ /**
+ * Get {@link ReferenceBean} {@link Map} in injected method.
+ *
+ * @return non-null {@link Map}
+ * @since 2.5.11
+ */
+ public Map<InjectionMetadata.InjectedElement, ReferenceBean<?>> getInjectedMethodReferenceBeanMap() {
+
+ Map<InjectionMetadata.InjectedElement, ReferenceBean<?>> injectedElementReferenceBeanMap =
+ new LinkedHashMap<InjectionMetadata.InjectedElement, ReferenceBean<?>>();
+
+ for (ReferenceInjectionMetadata metadata : injectionMetadataCache.values()) {
+
+ Collection<ReferenceMethodElement> methodElements = metadata.getMethodElements();
+
+ for (ReferenceMethodElement methodElement : methodElements) {
+
+ injectedElementReferenceBeanMap.put(methodElement, methodElement.referenceBean);
+
+ }
+
+ }
+
+ return injectedElementReferenceBeanMap;
+
+ }
+
+ private <T> T getFieldValue(Object object, String fieldName, Class<T> fieldType) {
+
+ Field field = ReflectionUtils.findField(object.getClass(), fieldName, fieldType);
+
+ ReflectionUtils.makeAccessible(field);
+
+ return (T) ReflectionUtils.getField(field, object);
+
+ }
+
+
}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java
index d2cc56d..5d9418f 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java
@@ -19,12 +19,18 @@ package com.alibaba.dubbo.config.spring.beans.factory.annotation;
import com.alibaba.dubbo.config.ConsumerConfig;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.spring.ReferenceBean;
+import com.alibaba.dubbo.config.spring.convert.converter.StringArrayToMapConverter;
+import com.alibaba.dubbo.config.spring.convert.converter.StringArrayToStringConverter;
import org.springframework.context.ApplicationContext;
+import org.springframework.core.convert.ConversionService;
+import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
+import org.springframework.validation.DataBinder;
import static com.alibaba.dubbo.config.spring.util.BeanFactoryUtils.getOptionalBean;
+import static com.alibaba.dubbo.config.spring.util.ObjectUtils.of;
/**
* {@link ReferenceBean} Builder
@@ -80,14 +86,30 @@ class ReferenceBeanBuilder extends AbstractAnnotationConfigBeanBuilder<Reference
@Override
protected ReferenceBean doBuild() {
- return new ReferenceBean<Object>(annotation);
+ return new ReferenceBean<Object>();
}
@Override
- protected void preConfigureBean(Reference annotation, ReferenceBean bean) {
+ protected void preConfigureBean(Reference reference, ReferenceBean referenceBean) {
Assert.notNull(interfaceClass, "The interface class must set first!");
+ DataBinder dataBinder = new DataBinder(referenceBean);
+ // Set ConversionService
+ dataBinder.setConversionService(getConversionService());
+ // Ignore those fields
+ String[] ignoreAttributeNames = of("application", "module", "consumer", "monitor", "registry");
+// dataBinder.setDisallowedFields(ignoreAttributeNames);
+ // Bind annotation attributes
+ dataBinder.bind(new AnnotationPropertyValuesAdapter(reference, applicationContext.getEnvironment(), ignoreAttributeNames));
}
+ private ConversionService getConversionService() {
+ DefaultConversionService conversionService = new DefaultConversionService();
+ conversionService.addConverter(new StringArrayToStringConverter());
+ conversionService.addConverter(new StringArrayToMapConverter());
+ return conversionService;
+ }
+
+
@Override
protected String resolveModuleConfigBeanName(Reference annotation) {
return annotation.module();
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
index 1d27345..207b3f7 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
@@ -21,20 +21,11 @@ import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.dubbo.config.spring.ServiceBean;
import com.alibaba.dubbo.config.spring.context.annotation.DubboClassPathBeanDefinitionScanner;
-
import org.springframework.beans.BeansException;
+import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.BeanClassLoaderAware;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.BeanDefinitionHolder;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.beans.factory.config.RuntimeBeanReference;
-import org.springframework.beans.factory.config.SingletonBeanRegistry;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
-import org.springframework.beans.factory.support.BeanNameGenerator;
-import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.config.*;
+import org.springframework.beans.factory.support.*;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
@@ -44,18 +35,11 @@ import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.filter.AnnotationTypeFilter;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.ObjectUtils;
-import org.springframework.util.StringUtils;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
+import org.springframework.util.*;
+
+import java.util.*;
+import static com.alibaba.dubbo.config.spring.util.ObjectUtils.of;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
import static org.springframework.context.annotation.AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR;
import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
@@ -356,11 +340,20 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr
private AbstractBeanDefinition buildServiceBeanDefinition(Service service, Class<?> interfaceClass,
String annotatedServiceBeanName) {
- BeanDefinitionBuilder builder = rootBeanDefinition(ServiceBean.class)
- .addConstructorArgValue(service)
- // References "ref" property to annotated-@Service Bean
- .addPropertyReference("ref", annotatedServiceBeanName)
- .addPropertyValue("interface", interfaceClass.getName());
+ BeanDefinitionBuilder builder = rootBeanDefinition(ServiceBean.class);
+
+ AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
+
+ MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
+
+ String[] ignoreAttributeNames = of("provider", "monitor", "application", "module", "registry", "protocol", "interface");
+
+ propertyValues.addPropertyValues(new AnnotationPropertyValuesAdapter(service, environment, ignoreAttributeNames));
+
+ // References "ref" property to annotated-@Service Bean
+ addPropertyReference(builder, "ref", annotatedServiceBeanName);
+ // Set interface
+ builder.addPropertyValue("interface", interfaceClass.getName());
/**
* Add {@link com.alibaba.dubbo.config.ProviderConfig} Bean reference
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingRegistrar.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingRegistrar.java
index cd9cadd..452d9d3 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingRegistrar.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingRegistrar.java
@@ -20,8 +20,6 @@ import com.alibaba.dubbo.config.AbstractConfig;
import com.alibaba.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.MutablePropertyValues;
-import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@@ -30,15 +28,21 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
-import org.springframework.core.env.*;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.Environment;
+import org.springframework.core.env.PropertySources;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
-import java.util.*;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
import static com.alibaba.dubbo.config.spring.util.PropertySourcesUtils.getSubProperties;
+import static com.alibaba.dubbo.config.spring.util.PropertySourcesUtils.normalizePrefix;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
import static org.springframework.beans.factory.support.BeanDefinitionReaderUtils.registerWithGeneratedName;
@@ -82,9 +86,7 @@ public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistra
boolean multiple,
BeanDefinitionRegistry registry) {
- PropertySources propertySources = environment.getPropertySources();
-
- Map<String, String> properties = getSubProperties(propertySources, prefix);
+ Map<String, String> properties = getSubProperties(environment.getPropertySources(), prefix);
if (CollectionUtils.isEmpty(properties)) {
if (log.isDebugEnabled()) {
@@ -94,16 +96,14 @@ public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistra
return;
}
- Set<String> beanNames = multiple ? resolveMultipleBeanNames(prefix, properties) :
- Collections.singleton(resolveSingleBeanName(configClass, properties, registry));
+ Set<String> beanNames = multiple ? resolveMultipleBeanNames(properties) :
+ Collections.singleton(resolveSingleBeanName(properties, configClass, registry));
for (String beanName : beanNames) {
registerDubboConfigBean(beanName, configClass, registry);
- MutablePropertyValues propertyValues = resolveBeanPropertyValues(beanName, multiple, properties);
-
- registerDubboConfigBindingBeanPostProcessor(beanName, propertyValues, registry);
+ registerDubboConfigBindingBeanPostProcessor(prefix, beanName, multiple, registry);
}
@@ -125,14 +125,16 @@ public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistra
}
- private void registerDubboConfigBindingBeanPostProcessor(String beanName, PropertyValues propertyValues,
+ private void registerDubboConfigBindingBeanPostProcessor(String prefix, String beanName, boolean multiple,
BeanDefinitionRegistry registry) {
Class<?> processorClass = DubboConfigBindingBeanPostProcessor.class;
BeanDefinitionBuilder builder = rootBeanDefinition(processorClass);
- builder.addConstructorArgValue(beanName).addConstructorArgValue(propertyValues);
+ String actualPrefix = multiple ? normalizePrefix(prefix) + beanName : prefix;
+
+ builder.addConstructorArgValue(actualPrefix).addConstructorArgValue(beanName);
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
@@ -147,36 +149,6 @@ public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistra
}
- private MutablePropertyValues resolveBeanPropertyValues(String beanName, boolean multiple,
- Map<String, String> properties) {
-
- MutablePropertyValues propertyValues = new MutablePropertyValues();
-
- if (multiple) { // For Multiple Beans
-
- MutablePropertySources propertySources = new MutablePropertySources();
- propertySources.addFirst(new MapPropertySource(beanName, new TreeMap<String, Object>(properties)));
-
- Map<String, String> subProperties = getSubProperties(propertySources, beanName);
-
- propertyValues.addPropertyValues(subProperties);
-
-
- } else { // For Single Bean
-
- for (Map.Entry<String, String> entry : properties.entrySet()) {
- String propertyName = entry.getKey();
- if (!propertyName.contains(".")) { // ignore property name with "."
- propertyValues.addPropertyValue(propertyName, entry.getValue());
- }
- }
-
- }
-
- return propertyValues;
-
- }
-
@Override
public void setEnvironment(Environment environment) {
@@ -186,7 +158,7 @@ public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistra
}
- private Set<String> resolveMultipleBeanNames(String prefix, Map<String, String> properties) {
+ private Set<String> resolveMultipleBeanNames(Map<String, String> properties) {
Set<String> beanNames = new LinkedHashSet<String>();
@@ -207,7 +179,7 @@ public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistra
}
- private String resolveSingleBeanName(Class<? extends AbstractConfig> configClass, Map<String, String> properties,
+ private String resolveSingleBeanName(Map<String, String> properties, Class<? extends AbstractConfig> configClass,
BeanDefinitionRegistry registry) {
String beanName = properties.get("id");
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/properties/AbstractDubboConfigBinder.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/properties/AbstractDubboConfigBinder.java
new file mode 100644
index 0000000..b103367
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/properties/AbstractDubboConfigBinder.java
@@ -0,0 +1,69 @@
+/*
+ * 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 com.alibaba.dubbo.config.spring.context.properties;
+
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.Environment;
+import org.springframework.core.env.PropertySource;
+
+/**
+ * Abstract {@link DubboConfigBinder} implementation
+ */
+public abstract class AbstractDubboConfigBinder implements DubboConfigBinder {
+
+ private Iterable<PropertySource<?>> propertySources;
+
+ private boolean ignoreUnknownFields = true;
+
+ private boolean ignoreInvalidFields = false;
+
+ /**
+ * Get multiple {@link PropertySource propertySources}
+ *
+ * @return multiple {@link PropertySource propertySources}
+ */
+ protected Iterable<PropertySource<?>> getPropertySources() {
+ return propertySources;
+ }
+
+ public boolean isIgnoreUnknownFields() {
+ return ignoreUnknownFields;
+ }
+
+ @Override
+ public void setIgnoreUnknownFields(boolean ignoreUnknownFields) {
+ this.ignoreUnknownFields = ignoreUnknownFields;
+ }
+
+ public boolean isIgnoreInvalidFields() {
+ return ignoreInvalidFields;
+ }
+
+ @Override
+ public void setIgnoreInvalidFields(boolean ignoreInvalidFields) {
+ this.ignoreInvalidFields = ignoreInvalidFields;
+ }
+
+ @Override
+ public final void setEnvironment(Environment environment) {
+
+ if (environment instanceof ConfigurableEnvironment) {
+ this.propertySources = ((ConfigurableEnvironment) environment).getPropertySources();
+ }
+
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/properties/DefaultDubboConfigBinder.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/properties/DefaultDubboConfigBinder.java
new file mode 100644
index 0000000..52cc87c
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/properties/DefaultDubboConfigBinder.java
@@ -0,0 +1,46 @@
+/*
+ * 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 com.alibaba.dubbo.config.spring.context.properties;
+
+import com.alibaba.dubbo.config.AbstractConfig;
+import org.springframework.beans.MutablePropertyValues;
+import org.springframework.validation.DataBinder;
+
+import java.util.Map;
+
+import static com.alibaba.dubbo.config.spring.util.PropertySourcesUtils.getSubProperties;
+
+/**
+ * Default {@link DubboConfigBinder} implementation based on Spring {@link DataBinder}
+ */
+public class DefaultDubboConfigBinder extends AbstractDubboConfigBinder {
+
+ @Override
+ public <C extends AbstractConfig> void bind(String prefix, C dubboConfig) {
+ DataBinder dataBinder = new DataBinder(dubboConfig);
+ // Set ignored*
+ dataBinder.setIgnoreInvalidFields(isIgnoreInvalidFields());
+ dataBinder.setIgnoreUnknownFields(isIgnoreUnknownFields());
+ // Get properties under specified prefix from PropertySources
+ Map<String, String> properties = getSubProperties(getPropertySources(), prefix);
+ // Convert Map to MutablePropertyValues
+ MutablePropertyValues propertyValues = new MutablePropertyValues(properties);
+ // Bind
+ dataBinder.bind(propertyValues);
+ }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/properties/DubboConfigBinder.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/properties/DubboConfigBinder.java
new file mode 100644
index 0000000..c19fadc
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/properties/DubboConfigBinder.java
@@ -0,0 +1,58 @@
+/*
+ * 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 com.alibaba.dubbo.config.spring.context.properties;
+
+import com.alibaba.dubbo.config.AbstractConfig;
+import org.springframework.context.EnvironmentAware;
+
+/**
+ * {@link AbstractConfig DubboConfig} Binder
+ *
+ * @see AbstractConfig
+ * @see EnvironmentAware
+ * @since 2.5.11
+ */
+public interface DubboConfigBinder extends EnvironmentAware {
+
+ /**
+ * Set whether to ignore unknown fields, that is, whether to ignore bind
+ * parameters that do not have corresponding fields in the target object.
+ * <p>Default is "true". Turn this off to enforce that all bind parameters
+ * must have a matching field in the target object.
+ *
+ * @see #bind
+ */
+ void setIgnoreUnknownFields(boolean ignoreUnknownFields);
+
+ /**
+ * Set whether to ignore invalid fields, that is, whether to ignore bind
+ * parameters that have corresponding fields in the target object which are
+ * not accessible (for example because of null values in the nested path).
+ * <p>Default is "false".
+ *
+ * @see #bind
+ */
+ void setIgnoreInvalidFields(boolean ignoreInvalidFields);
+
+ /**
+ * Bind the properties to {@link C Dubbo Config} Object under specified prefix.
+ *
+ * @param prefix
+ * @param dubboConfig
+ */
+ <C extends AbstractConfig> void bind(String prefix, C dubboConfig);
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToMapConverter.java
similarity index 57%
copy from dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java
copy to dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToMapConverter.java
index 7766a1a..56c6d4c 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToMapConverter.java
@@ -1,37 +1,38 @@
-/*
- * 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 com.alibaba.dubbo.config.spring.annotation.provider;
-
-import com.alibaba.dubbo.config.annotation.Service;
-import com.alibaba.dubbo.config.spring.api.Box;
-import com.alibaba.dubbo.config.spring.api.DemoService;
-
-/**
- * DemoServiceImpl
- */
-@Service(version = "1.2")
-public class AnnotationServiceImpl implements DemoService {
-
- public String sayName(String name) {
- return "annotation:" + name;
- }
-
- public Box getBox() {
- return null;
- }
-
-}
\ No newline at end of file
+/*
+ * 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 com.alibaba.dubbo.config.spring.convert.converter;
+
+import com.alibaba.dubbo.common.utils.CollectionUtils;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.util.ObjectUtils;
+
+import java.util.Map;
+
+/**
+ * {@link String}[] to {@link Map} {@link Converter}
+ *
+ * @see CollectionUtils#toStringMap(String[])
+ * @since 2.5.11
+ */
+public class StringArrayToMapConverter implements Converter<String[], Map<String, String>> {
+
+ @Override
+ public Map<String, String> convert(String[] source) {
+ return ObjectUtils.isEmpty(source) ? null : CollectionUtils.toStringMap(source);
+ }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToStringConverter.java
similarity index 58%
copy from dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java
copy to dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToStringConverter.java
index 7766a1a..23e948b 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToStringConverter.java
@@ -1,37 +1,37 @@
-/*
- * 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 com.alibaba.dubbo.config.spring.annotation.provider;
-
-import com.alibaba.dubbo.config.annotation.Service;
-import com.alibaba.dubbo.config.spring.api.Box;
-import com.alibaba.dubbo.config.spring.api.DemoService;
-
-/**
- * DemoServiceImpl
- */
-@Service(version = "1.2")
-public class AnnotationServiceImpl implements DemoService {
-
- public String sayName(String name) {
- return "annotation:" + name;
- }
-
- public Box getBox() {
- return null;
- }
-
-}
\ No newline at end of file
+/*
+ * 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 com.alibaba.dubbo.config.spring.convert.converter;
+
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.util.ObjectUtils;
+import org.springframework.util.StringUtils;
+
+
+/**
+ * String[] to String {@ConditionalGenericConverter}
+ *
+ * @see StringUtils#arrayToCommaDelimitedString(Object[])
+ * @since 2.5.11
+ */
+public class StringArrayToStringConverter implements Converter<String[], String> {
+
+ @Override
+ public String convert(String[] source) {
+ return ObjectUtils.isEmpty(source) ? null : StringUtils.arrayToCommaDelimitedString(source);
+ }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/AnnotationUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/AnnotationUtils.java
new file mode 100644
index 0000000..aa15e56
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/AnnotationUtils.java
@@ -0,0 +1,89 @@
+/*
+ * 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 com.alibaba.dubbo.config.spring.util;
+
+import org.springframework.core.env.PropertyResolver;
+
+import java.lang.annotation.Annotation;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import static java.lang.String.valueOf;
+import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes;
+import static org.springframework.core.annotation.AnnotationUtils.getDefaultValue;
+import static org.springframework.util.CollectionUtils.arrayToList;
+import static org.springframework.util.ObjectUtils.nullSafeEquals;
+import static org.springframework.util.StringUtils.trimAllWhitespace;
+
+/**
+ * Annotation Utilities Class
+ *
+ * @see org.springframework.core.annotation.AnnotationUtils
+ * @since 2.5.11
+ */
+public class AnnotationUtils {
+
+ /**
+ * Get {@link Annotation} attributes
+ *
+ * @param annotation
+ * @param propertyResolver
+ * @param ignoreDefaultValue
+ * @return non-null
+ */
+ public static Map<String, Object> getAttributes(Annotation annotation, PropertyResolver propertyResolver,
+ boolean ignoreDefaultValue, String... ignoreAttributeNames) {
+
+ Set<String> ignoreAttributeNamesSet = new HashSet<String>(arrayToList(ignoreAttributeNames));
+
+ Map<String, Object> attributes = getAnnotationAttributes(annotation);
+
+ Map<String, Object> actualAttributes = new LinkedHashMap<String, Object>();
+
+ boolean requiredResolve = propertyResolver != null;
+
+ for (Map.Entry<String, Object> entry : attributes.entrySet()) {
+
+ String attributeName = entry.getKey();
+ Object attributeValue = entry.getValue();
+
+ // ignore default attribute value
+ if (ignoreDefaultValue && nullSafeEquals(attributeValue, getDefaultValue(annotation, attributeName))) {
+ continue;
+ }
+
+ // ignore attribute name
+ if (ignoreAttributeNamesSet.contains(attributeName)) {
+ continue;
+ }
+
+ if (requiredResolve && attributeValue instanceof String) { // Resolve Placeholder
+ String resolvedValue = propertyResolver.resolvePlaceholders(valueOf(attributeValue));
+ attributeValue = trimAllWhitespace(resolvedValue);
+ }
+
+ actualAttributes.put(attributeName, attributeValue);
+
+ }
+
+ return actualAttributes;
+
+ }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/ObjectUtils.java
similarity index 62%
copy from dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java
copy to dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/ObjectUtils.java
index 7766a1a..00db1e7 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/ObjectUtils.java
@@ -1,37 +1,37 @@
-/*
- * 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 com.alibaba.dubbo.config.spring.annotation.provider;
-
-import com.alibaba.dubbo.config.annotation.Service;
-import com.alibaba.dubbo.config.spring.api.Box;
-import com.alibaba.dubbo.config.spring.api.DemoService;
-
-/**
- * DemoServiceImpl
- */
-@Service(version = "1.2")
-public class AnnotationServiceImpl implements DemoService {
-
- public String sayName(String name) {
- return "annotation:" + name;
- }
-
- public Box getBox() {
- return null;
- }
-
-}
\ No newline at end of file
+/*
+ * 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 com.alibaba.dubbo.config.spring.util;
+
+/**
+ * Object Utilities Class
+ *
+ * @since 2.5.11
+ */
+public class ObjectUtils {
+
+ /**
+ * of factory method
+ *
+ * @param values
+ * @param <T>
+ * @return
+ */
+ public static <T> T[] of(T... values) {
+ return values;
+ }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/PropertySourcesUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/PropertySourcesUtils.java
index fe1c61b..5b183e1 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/PropertySourcesUtils.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/PropertySourcesUtils.java
@@ -35,16 +35,16 @@ public abstract class PropertySourcesUtils {
/**
* Get Sub {@link Properties}
*
- * @param propertySources {@link PropertySources}
+ * @param propertySources {@link PropertySource} Iterable
* @param prefix the prefix of property name
- * @return Map<String, String>
+ * @return Map<String , [...]
* @see Properties
*/
- public static Map<String, String> getSubProperties(PropertySources propertySources, String prefix) {
+ public static Map<String, String> getSubProperties(Iterable<PropertySource<?>> propertySources, String prefix) {
Map<String, String> subProperties = new LinkedHashMap<String, String>();
- String normalizedPrefix = prefix.endsWith(".") ? prefix : prefix + ".";
+ String normalizedPrefix = normalizePrefix(prefix);
for (PropertySource<?> source : propertySources) {
if (source instanceof EnumerablePropertySource) {
@@ -62,4 +62,14 @@ public abstract class PropertySourcesUtils {
}
+ /**
+ * Normalize the prefix
+ *
+ * @param prefix the prefix
+ * @return the prefix
+ */
+ public static String normalizePrefix(String prefix) {
+ return prefix.endsWith(".") ? prefix : prefix + ".";
+ }
+
}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java
index 7766a1a..327f4d9 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java
@@ -23,7 +23,7 @@ import com.alibaba.dubbo.config.spring.api.DemoService;
/**
* DemoServiceImpl
*/
-@Service(version = "1.2")
+@Service(version = "${provider.version}")
public class AnnotationServiceImpl implements DemoService {
public String sayName(String name) {
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapterTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapterTest.java
new file mode 100644
index 0000000..36def71
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapterTest.java
@@ -0,0 +1,158 @@
+/*
+ * 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 com.alibaba.dubbo.config.spring.beans.factory.annotation;
+
+
+import com.alibaba.dubbo.common.utils.CollectionUtils;
+import com.alibaba.dubbo.config.annotation.Reference;
+import com.alibaba.dubbo.config.spring.ReferenceBean;
+import com.alibaba.dubbo.config.spring.api.DemoService;
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.core.convert.support.DefaultConversionService;
+import org.springframework.mock.env.MockEnvironment;
+import org.springframework.util.ReflectionUtils;
+import org.springframework.validation.DataBinder;
+
+import java.lang.reflect.Field;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import static org.springframework.util.StringUtils.arrayToCommaDelimitedString;
+
+/**
+ * {@link AnnotationPropertyValuesAdapter} Test
+ *
+ * @since 2.5.11
+ */
+public class AnnotationPropertyValuesAdapterTest {
+
+ @Test
+ public void test() {
+
+ MockEnvironment mockEnvironment = new MockEnvironment();
+
+ mockEnvironment.setProperty("version", "1.0.0");
+
+ mockEnvironment.setProperty("url", " dubbo://localhost:12345");
+
+ Field field = ReflectionUtils.findField(TestBean.class, "demoService");
+
+ Reference reference = AnnotationUtils.getAnnotation(field, Reference.class);
+
+ AnnotationPropertyValuesAdapter propertyValues = new AnnotationPropertyValuesAdapter(reference, mockEnvironment);
+
+ ReferenceBean referenceBean = new ReferenceBean();
+
+ DataBinder dataBinder = new DataBinder(referenceBean);
+
+ dataBinder.setDisallowedFields("application", "module", "consumer", "monitor", "registry");
+
+ DefaultConversionService conversionService = new DefaultConversionService();
+
+ conversionService.addConverter(new Converter<String[], String>() {
+ @Override
+ public String convert(String[] source) {
+ return arrayToCommaDelimitedString(source);
+ }
+ });
+
+ conversionService.addConverter(new Converter<String[], Map<String, String>>() {
+ @Override
+ public Map<String, String> convert(String[] source) {
+ return CollectionUtils.toStringMap(source);
+ }
+ });
+
+
+ dataBinder.setConversionService(conversionService);
+
+
+ dataBinder.bind(propertyValues);
+
+// System.out.println(referenceBean);
+
+ Assert.assertEquals(DemoService.class, referenceBean.getInterfaceClass());
+ Assert.assertEquals("com.alibaba.dubbo.config.spring.api.DemoService", referenceBean.getInterface());
+ Assert.assertEquals("1.0.0", referenceBean.getVersion());
+ Assert.assertEquals("group", referenceBean.getGroup());
+ Assert.assertEquals("dubbo://localhost:12345", referenceBean.getUrl());
+ Assert.assertEquals("client", referenceBean.getClient());
+ Assert.assertEquals(true, referenceBean.isGeneric());
+ Assert.assertEquals(true, referenceBean.isInjvm());
+ Assert.assertEquals(false, referenceBean.isCheck());
+ Assert.assertEquals(true, referenceBean.isInit());
+ Assert.assertEquals(true, referenceBean.getLazy());
+ Assert.assertEquals(true, referenceBean.getStubevent());
+ Assert.assertEquals("reconnect", referenceBean.getReconnect());
+ Assert.assertEquals(true, referenceBean.getSticky());
+
+ Assert.assertEquals("javassist", referenceBean.getProxy());
+
+ Assert.assertEquals("stub", referenceBean.getStub());
+ Assert.assertEquals("failover", referenceBean.getCluster());
+ Assert.assertEquals(Integer.valueOf(1), referenceBean.getConnections());
+ Assert.assertEquals(Integer.valueOf(1), referenceBean.getCallbacks());
+ Assert.assertEquals("onconnect", referenceBean.getOnconnect());
+ Assert.assertEquals("ondisconnect", referenceBean.getOndisconnect());
+ Assert.assertEquals("owner", referenceBean.getOwner());
+ Assert.assertEquals("layer", referenceBean.getLayer());
+ Assert.assertEquals(Integer.valueOf(2), referenceBean.getRetries());
+ Assert.assertEquals("random", referenceBean.getLoadbalance());
+ Assert.assertEquals(true, referenceBean.isAsync());
+ Assert.assertEquals(Integer.valueOf(1), referenceBean.getActives());
+ Assert.assertEquals(true, referenceBean.getSent());
+ Assert.assertEquals("mock", referenceBean.getMock());
+ Assert.assertEquals("validation", referenceBean.getValidation());
+ Assert.assertEquals(Integer.valueOf(2), referenceBean.getTimeout());
+ Assert.assertEquals("cache", referenceBean.getCache());
+ Assert.assertEquals("default,default", referenceBean.getFilter());
+ Assert.assertEquals("default,default", referenceBean.getListener());
+
+ Map<String, String> data = new LinkedHashMap<String, String>();
+ data.put("key1", "value1");
+
+ Assert.assertEquals(data, referenceBean.getParameters());
+ // Bean compare
+ Assert.assertEquals(null, referenceBean.getApplication());
+ Assert.assertEquals(null, referenceBean.getModule());
+ Assert.assertEquals(null, referenceBean.getConsumer());
+ Assert.assertEquals(null, referenceBean.getMonitor());
+ Assert.assertEquals(null, referenceBean.getRegistry());
+
+ }
+
+ private static class TestBean {
+
+ @Reference(
+ interfaceClass = DemoService.class, interfaceName = "com.alibaba.dubbo.config.spring.api.DemoService", version = "${version}", group = "group",
+ url = "${url} ", client = "client", generic = true, injvm = true,
+ check = false, init = true, lazy = true, stubevent = true,
+ reconnect = "reconnect", sticky = true, proxy = "javassist", stub = "stub",
+ cluster = "failover", connections = 1, callbacks = 1, onconnect = "onconnect",
+ ondisconnect = "ondisconnect", owner = "owner", layer = "layer", retries = 2,
+ loadbalance = "random", async = true, actives = 1, sent = true,
+ mock = "mock", validation = "validation", timeout = 2, cache = "cache",
+ filter = {"default", "default"}, listener = {"default", "default"}, parameters = {"key1", "value1"}, application = "application",
+ module = "module", consumer = "consumer", monitor = "monitor", registry = {"registry1", "registry2"}
+ )
+ private DemoService demoService;
+
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/DubboConfigBindingBeanPostProcessorTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/DubboConfigBindingBeanPostProcessorTest.java
new file mode 100644
index 0000000..05a4980
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/DubboConfigBindingBeanPostProcessorTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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 com.alibaba.dubbo.config.spring.beans.factory.annotation;
+
+import com.alibaba.dubbo.config.ApplicationConfig;
+import com.alibaba.dubbo.config.spring.context.properties.DefaultDubboConfigBinder;
+import com.alibaba.dubbo.config.spring.context.properties.DubboConfigBinder;
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+
+import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
+
+/**
+ * {@link DubboConfigBindingBeanPostProcessor}
+ */
+@PropertySource({"classpath:/META-INF/config.properties"})
+@Configuration
+public class DubboConfigBindingBeanPostProcessorTest {
+
+ @Bean("applicationBean")
+ public ApplicationConfig applicationConfig() {
+ return new ApplicationConfig();
+ }
+
+ @Bean
+ public DubboConfigBinder dubboConfigBinder() {
+ return new DefaultDubboConfigBinder();
+ }
+
+ @Test
+ public void test() {
+
+ final AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
+
+ applicationContext.register(getClass());
+
+ Class<?> processorClass = DubboConfigBindingBeanPostProcessor.class;
+
+ applicationContext.registerBeanDefinition("DubboConfigBindingBeanPostProcessor", rootBeanDefinition(processorClass).addConstructorArgValue("dubbo.application").addConstructorArgValue("applicationBean").getBeanDefinition());
+
+ applicationContext.refresh();
+
+ ApplicationConfig applicationConfig = applicationContext.getBean(ApplicationConfig.class);
+
+ Assert.assertEquals("dubbo-demo-application", applicationConfig.getName());
+
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
index 3f9a50e..5f33491 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
@@ -20,16 +20,16 @@ import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.spring.ReferenceBean;
import com.alibaba.dubbo.config.spring.api.DemoService;
import com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScan;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.*;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.InjectionMetadata;
import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ImportResource;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Collection;
+import java.util.Map;
import static com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor.BEAN_NAME;
@@ -40,12 +40,27 @@ import static com.alibaba.dubbo.config.spring.beans.factory.annotation.Reference
*/
public class ReferenceAnnotationBeanPostProcessorTest {
- private static final String PROVIDER_LOCATION = "META-INF/spring/dubbo-provider.xml";
+ private ConfigurableApplicationContext providerApplicationContext;
+
+ @BeforeClass
+ public static void prepare() {
+ System.setProperty("provider.version", "1.2");
+ System.setProperty("package1", "com.alibaba.dubbo.config.spring.annotation.provider");
+ System.setProperty("packagesToScan", "${package1}");
+ System.setProperty("consumer.version", "1.2");
+ System.setProperty("consumer.url", "dubbo://127.0.0.1:12345");
+ }
@Before
- public void before() {
+ public void init() {
// Starts Provider
- new ClassPathXmlApplicationContext(PROVIDER_LOCATION);
+ providerApplicationContext = new AnnotationConfigApplicationContext(ServiceAnnotationBeanPostProcessorTest.TestConfiguration.class);
+ }
+
+ @After
+ public void destroy() {
+ // Shutdowns Provider
+ providerApplicationContext.close();
}
@Test
@@ -95,6 +110,66 @@ public class ReferenceAnnotationBeanPostProcessorTest {
}
+ @Test
+ public void testGetInjectedFieldReferenceBeanMap() {
+
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestBean.class);
+
+ ReferenceAnnotationBeanPostProcessor beanPostProcessor = context.getBean(BEAN_NAME,
+ ReferenceAnnotationBeanPostProcessor.class);
+
+
+ Map<InjectionMetadata.InjectedElement, ReferenceBean<?>> referenceBeanMap =
+ beanPostProcessor.getInjectedFieldReferenceBeanMap();
+
+ Assert.assertEquals(1, referenceBeanMap.size());
+
+ for (Map.Entry<InjectionMetadata.InjectedElement, ReferenceBean<?>> entry : referenceBeanMap.entrySet()) {
+
+ InjectionMetadata.InjectedElement injectedElement = entry.getKey();
+
+ Assert.assertEquals("com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor$ReferenceFieldElement",
+ injectedElement.getClass().getName());
+
+ ReferenceBean<?> referenceBean = entry.getValue();
+
+ Assert.assertEquals("1.2", referenceBean.getVersion());
+ Assert.assertEquals("dubbo://127.0.0.1:12345", referenceBean.getUrl());
+
+ }
+
+ }
+
+ @Test
+ public void testGetInjectedMethodReferenceBeanMap() {
+
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestBean.class);
+
+ ReferenceAnnotationBeanPostProcessor beanPostProcessor = context.getBean(BEAN_NAME,
+ ReferenceAnnotationBeanPostProcessor.class);
+
+
+ Map<InjectionMetadata.InjectedElement, ReferenceBean<?>> referenceBeanMap =
+ beanPostProcessor.getInjectedMethodReferenceBeanMap();
+
+ Assert.assertEquals(2, referenceBeanMap.size());
+
+ for (Map.Entry<InjectionMetadata.InjectedElement, ReferenceBean<?>> entry : referenceBeanMap.entrySet()) {
+
+ InjectionMetadata.InjectedElement injectedElement = entry.getKey();
+
+ Assert.assertEquals("com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor$ReferenceMethodElement",
+ injectedElement.getClass().getName());
+
+ ReferenceBean<?> referenceBean = entry.getValue();
+
+ Assert.assertEquals("1.2", referenceBean.getVersion());
+ Assert.assertEquals("dubbo://127.0.0.1:12345", referenceBean.getUrl());
+
+ }
+
+ }
+
private static class AncestorBean {
@@ -121,7 +196,7 @@ public class ReferenceAnnotationBeanPostProcessorTest {
private static class ParentBean extends AncestorBean {
- @Reference(version = "1.2", url = "dubbo://127.0.0.1:12345")
+ @Reference(version = "${consumer.version}", url = "${consumer.url}")
private DemoService demoServiceFromParent;
public DemoService getDemoServiceFromParent() {
@@ -133,7 +208,7 @@ public class ReferenceAnnotationBeanPostProcessorTest {
@ImportResource("META-INF/spring/dubbo-annotation-consumer.xml")
@DubboComponentScan(basePackageClasses = ReferenceAnnotationBeanPostProcessorTest.class)
- private static class TestBean extends ParentBean {
+ static class TestBean extends ParentBean {
private DemoService demoService;
@@ -150,4 +225,4 @@ public class ReferenceAnnotationBeanPostProcessorTest {
}
}
-}
+}
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessorTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessorTest.java
index e5714c7..c096441 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessorTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessorTest.java
@@ -44,7 +44,8 @@ import java.util.Map;
classes = {ServiceAnnotationBeanPostProcessorTest.TestConfiguration.class})
@TestPropertySource(properties = {
"package1 = com.alibaba.dubbo.config.spring.context.annotation",
- "packagesToScan = ${package1}"
+ "packagesToScan = ${package1}",
+ "provider.version = 1.2"
})
public class ServiceAnnotationBeanPostProcessorTest {
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/properties/DefaultDubboConfigBinderTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/properties/DefaultDubboConfigBinderTest.java
new file mode 100644
index 0000000..f0ec69f
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/properties/DefaultDubboConfigBinderTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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 com.alibaba.dubbo.config.spring.context.properties;
+
+
+import com.alibaba.dubbo.config.ApplicationConfig;
+import com.alibaba.dubbo.config.ProtocolConfig;
+import com.alibaba.dubbo.config.RegistryConfig;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@TestPropertySource(locations = "classpath:/dubbo.properties")
+@ContextConfiguration(classes = DefaultDubboConfigBinder.class)
+public class DefaultDubboConfigBinderTest {
+
+ @Autowired
+ private DubboConfigBinder dubboConfigBinder;
+
+ @Test
+ public void testBinder() {
+
+ ApplicationConfig applicationConfig = new ApplicationConfig();
+ dubboConfigBinder.bind("dubbo.application", applicationConfig);
+ Assert.assertEquals("hello", applicationConfig.getName());
+ Assert.assertEquals("world", applicationConfig.getOwner());
+
+ RegistryConfig registryConfig = new RegistryConfig();
+ dubboConfigBinder.bind("dubbo.registry", registryConfig);
+ Assert.assertEquals("10.20.153.17", registryConfig.getAddress());
+
+ ProtocolConfig protocolConfig = new ProtocolConfig();
+ dubboConfigBinder.bind("dubbo.protocol", protocolConfig);
+ Assert.assertEquals(Integer.valueOf(20881), protocolConfig.getPort());
+
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToMapConverterTest.java
similarity index 50%
copy from dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java
copy to dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToMapConverterTest.java
index 7766a1a..51be7c3 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToMapConverterTest.java
@@ -1,37 +1,52 @@
-/*
- * 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 com.alibaba.dubbo.config.spring.annotation.provider;
-
-import com.alibaba.dubbo.config.annotation.Service;
-import com.alibaba.dubbo.config.spring.api.Box;
-import com.alibaba.dubbo.config.spring.api.DemoService;
-
-/**
- * DemoServiceImpl
- */
-@Service(version = "1.2")
-public class AnnotationServiceImpl implements DemoService {
-
- public String sayName(String name) {
- return "annotation:" + name;
- }
-
- public Box getBox() {
- return null;
- }
-
-}
\ No newline at end of file
+/*
+ * 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 com.alibaba.dubbo.config.spring.convert.converter;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * {@link StringArrayToMapConverter} Test
+ */
+public class StringArrayToMapConverterTest {
+
+ @Test
+ public void testConvert() {
+
+ StringArrayToMapConverter converter = new StringArrayToMapConverter();
+
+ Map<String, String> value = converter.convert(new String[]{"Hello", "World"});
+
+ Map<String, String> expected = new LinkedHashMap<String, String>();
+
+ expected.put("Hello", "World");
+
+ Assert.assertEquals(expected, value);
+
+ value = converter.convert(new String[]{});
+
+ Assert.assertNull(value);
+
+ value = converter.convert(null);
+
+ Assert.assertNull(value);
+
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToStringConverterTest.java
similarity index 56%
copy from dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java
copy to dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToStringConverterTest.java
index 7766a1a..67e8247 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/annotation/provider/AnnotationServiceImpl.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToStringConverterTest.java
@@ -1,37 +1,46 @@
-/*
- * 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 com.alibaba.dubbo.config.spring.annotation.provider;
-
-import com.alibaba.dubbo.config.annotation.Service;
-import com.alibaba.dubbo.config.spring.api.Box;
-import com.alibaba.dubbo.config.spring.api.DemoService;
-
-/**
- * DemoServiceImpl
- */
-@Service(version = "1.2")
-public class AnnotationServiceImpl implements DemoService {
-
- public String sayName(String name) {
- return "annotation:" + name;
- }
-
- public Box getBox() {
- return null;
- }
-
-}
\ No newline at end of file
+/*
+ * 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 com.alibaba.dubbo.config.spring.convert.converter;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * {@link StringArrayToStringConverter} Test
+ */
+public class StringArrayToStringConverterTest {
+
+ @Test
+ public void testConvert() {
+
+ StringArrayToStringConverter converter = new StringArrayToStringConverter();
+
+ String value = converter.convert(new String[]{"Hello", "World"});
+
+ Assert.assertEquals("Hello,World", value);
+
+ value = converter.convert(new String[]{});
+
+ Assert.assertNull(value);
+
+ value = converter.convert(null);
+
+ Assert.assertNull(value);
+
+ }
+
+}
--
To stop receiving notification emails like this one, please contact
mercyblitz@apache.org.