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 <mercybl...@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
mercybl...@apache.org.

Reply via email to