You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@dubbo.apache.org by GitBox <gi...@apache.org> on 2018/04/23 13:31:07 UTC

[GitHub] mercyblitz closed pull request #1662: [BUG] Refactor @Service annotation bean name

mercyblitz closed pull request #1662: [BUG] Refactor @Service annotation bean name
URL: https://github.com/apache/incubator-dubbo/pull/1662
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ReferenceBean.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ReferenceBean.java
index f3aa9b0249..a9d5b3f58c 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ReferenceBean.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ReferenceBean.java
@@ -25,7 +25,6 @@
 import com.alibaba.dubbo.config.annotation.Reference;
 import com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory;
 import com.alibaba.dubbo.config.support.Parameter;
-
 import org.springframework.beans.factory.BeanFactoryUtils;
 import org.springframework.beans.factory.DisposableBean;
 import org.springframework.beans.factory.FactoryBean;
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ServiceBean.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ServiceBean.java
index 2e614efdb6..c4eb0c2821 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ServiceBean.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ServiceBean.java
@@ -25,7 +25,6 @@
 import com.alibaba.dubbo.config.ServiceConfig;
 import com.alibaba.dubbo.config.annotation.Service;
 import com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory;
-
 import org.springframework.aop.support.AopUtils;
 import org.springframework.beans.factory.BeanFactoryUtils;
 import org.springframework.beans.factory.BeanNameAware;
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 0000000000..751399f849
--- /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 6899ad42fc..cbb5435d33 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,16 +17,19 @@
 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 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.config.BeanPostProcessor;
-import org.springframework.validation.DataBinder;
-
-import java.util.Arrays;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.core.env.Environment;
 
 /**
  * Dubbo Config Binding {@link BeanPostProcessor}
@@ -35,43 +38,52 @@
  * @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 +91,70 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) thro
 
     }
 
+    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 d8411de364..cfd719668a 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.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,12 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
@@ -73,8 +77,8 @@
 
     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 +105,9 @@ public PropertyValues postProcessPropertyValues(
      * @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 +140,9 @@ public void doWith(Field field) throws IllegalArgumentException, IllegalAccessEx
      * @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 +184,10 @@ public void doWith(Method method) throws IllegalArgumentException, IllegalAccess
      * @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 +195,7 @@ private InjectionMetadata findReferenceMetadata(String beanName, Class<?> clazz,
         // 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 +269,43 @@ public void setBeanClassLoader(ClassLoader classLoader) {
         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 +315,8 @@ public void setBeanClassLoader(ClassLoader classLoader) {
 
         private final Reference reference;
 
+        private volatile ReferenceBean<?> referenceBean;
+
         protected ReferenceMethodElement(Method method, PropertyDescriptor pd, Reference reference) {
             super(method, pd);
             this.method = method;
@@ -290,11 +328,11 @@ protected void inject(Object bean, String beanName, PropertyValues pvs) throws T
 
             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 +347,8 @@ protected void inject(Object bean, String beanName, PropertyValues pvs) throws T
 
         private final Reference reference;
 
+        private volatile ReferenceBean<?> referenceBean;
+
         protected ReferenceFieldElement(Field field, Reference reference) {
             super(field, null);
             this.field = field;
@@ -320,17 +360,17 @@ protected void inject(Object bean, String beanName, PropertyValues pvs) throws T
 
             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 +388,8 @@ private Object buildReferenceBean(Reference reference, Class<?> referenceClass)
 
         }
 
+        return referenceBean;
 
-        return referenceBean.get();
     }
 
 
@@ -360,11 +400,17 @@ private Object buildReferenceBean(Reference reference, Class<?> referenceClass)
      * @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 +436,70 @@ private static String resolveInterfaceName(Reference reference, Class<?> beanCla
 
     }
 
+
+    /**
+     * 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 d2cc56d2bf..5d9418fbc8 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 @@
 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 @@ private void configureConsumerConfig(Reference reference, ReferenceBean<?> refer
 
     @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 1d273451bf..d3ca42ea34 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,8 +21,8 @@
 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;
@@ -56,6 +56,7 @@
 import java.util.List;
 import java.util.Set;
 
+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;
@@ -70,6 +71,8 @@
 public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware,
         ResourceLoaderAware, BeanClassLoaderAware {
 
+    private static final String SEPARATOR = ":";
+
     private final Logger logger = LoggerFactory.getLogger(getClass());
 
     private final Set<String> packagesToScan;
@@ -253,7 +256,7 @@ private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, Bean
                 buildServiceBeanDefinition(service, interfaceClass, annotatedServiceBeanName);
 
         // ServiceBean Bean name
-        String beanName = generateServiceBeanName(interfaceClass, annotatedServiceBeanName);
+        String beanName = generateServiceBeanName(service, interfaceClass, annotatedServiceBeanName);
 
         if (scanner.checkCandidate(beanName, serviceBeanDefinition)) { // check duplicated candidate bean
             registry.registerBeanDefinition(beanName, serviceBeanDefinition);
@@ -278,14 +281,35 @@ private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, Bean
     /**
      * Generates the bean name of {@link ServiceBean}
      *
+     * @param service
      * @param interfaceClass           the class of interface annotated {@link Service}
      * @param annotatedServiceBeanName the bean name of annotated {@link Service}
      * @return ServiceBean@interfaceClassName#annotatedServiceBeanName
      * @since 2.5.9
      */
-    private String generateServiceBeanName(Class<?> interfaceClass, String annotatedServiceBeanName) {
+    private String generateServiceBeanName(Service service, Class<?> interfaceClass, String annotatedServiceBeanName) {
+
+        StringBuilder beanNameBuilder = new StringBuilder(ServiceBean.class.getSimpleName());
+
+        beanNameBuilder.append(SEPARATOR).append(annotatedServiceBeanName);
+
+        String interfaceClassName = interfaceClass.getName();
+
+        beanNameBuilder.append(SEPARATOR).append(interfaceClassName);
+
+        String version = service.version();
+
+        if (StringUtils.hasText(version)) {
+            beanNameBuilder.append(SEPARATOR).append(version);
+        }
 
-        return "ServiceBean@" + interfaceClass.getName() + "#" + annotatedServiceBeanName;
+        String group = service.group();
+
+        if (StringUtils.hasText(group)) {
+            beanNameBuilder.append(SEPARATOR).append(group);
+        }
+
+        return beanNameBuilder.toString();
 
     }
 
@@ -356,11 +380,20 @@ private String generateServiceBeanName(Class<?> interfaceClass, String annotated
     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
@@ -413,7 +446,7 @@ private AbstractBeanDefinition buildServiceBeanDefinition(Service service, Class
 
         List<RuntimeBeanReference> protocolRuntimeBeanReferences = toRuntimeBeanReferences(protocolConfigBeanNames);
 
-        if (!registryRuntimeBeanReferences.isEmpty()) {
+        if (!protocolRuntimeBeanReferences.isEmpty()) {
             builder.addPropertyValue("protocols", protocolRuntimeBeanReferences);
         }
 
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 f9013b449c..6936787cc6 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.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;
@@ -32,9 +30,6 @@
 import org.springframework.core.annotation.AnnotationAttributes;
 import org.springframework.core.env.ConfigurableEnvironment;
 import org.springframework.core.env.Environment;
-import org.springframework.core.env.MapPropertySource;
-import org.springframework.core.env.MutablePropertySources;
-import org.springframework.core.env.PropertySources;
 import org.springframework.core.type.AnnotationMetadata;
 import org.springframework.util.Assert;
 import org.springframework.util.CollectionUtils;
@@ -44,9 +39,9 @@
 import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
-import java.util.TreeMap;
 
 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;
 
@@ -90,9 +85,7 @@ private void registerDubboConfigBeans(String prefix,
                                           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()) {
@@ -102,16 +95,14 @@ private void registerDubboConfigBeans(String prefix,
             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);
 
         }
 
@@ -133,14 +124,16 @@ private void registerDubboConfigBean(String beanName, Class<? extends AbstractCo
 
     }
 
-    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();
 
@@ -155,36 +148,6 @@ private void registerDubboConfigBindingBeanPostProcessor(String beanName, Proper
 
     }
 
-    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) {
 
@@ -194,7 +157,7 @@ public void setEnvironment(Environment environment) {
 
     }
 
-    private Set<String> resolveMultipleBeanNames(String prefix, Map<String, String> properties) {
+    private Set<String> resolveMultipleBeanNames(Map<String, String> properties) {
 
         Set<String> beanNames = new LinkedHashSet<String>();
 
@@ -215,7 +178,7 @@ public void setEnvironment(Environment environment) {
 
     }
 
-    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 0000000000..b10336797f
--- /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 0000000000..52cc87ca4f
--- /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 0000000000..6ebb86296d
--- /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 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/main/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToMapConverter.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToMapConverter.java
new file mode 100644
index 0000000000..56c6d4c4cc
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToMapConverter.java
@@ -0,0 +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.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/main/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToStringConverter.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToStringConverter.java
new file mode 100644
index 0000000000..23e948b064
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToStringConverter.java
@@ -0,0 +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.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 0000000000..aa15e567eb
--- /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/main/java/com/alibaba/dubbo/config/spring/util/ObjectUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/ObjectUtils.java
new file mode 100644
index 0000000000..00db1e770f
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/ObjectUtils.java
@@ -0,0 +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.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 fe1c61bbbd..5b183e1f2f 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 @@
     /**
      * 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                                                                                                                                                                                                                                                               ,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               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 @@
 
     }
 
+    /**
+     * 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/ConfigTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/ConfigTest.java
index 3b54e9d8a5..80de429007 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/ConfigTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/ConfigTest.java
@@ -21,7 +21,13 @@
 import com.alibaba.dubbo.common.extension.ExtensionLoader;
 import com.alibaba.dubbo.common.utils.NetUtils;
 import com.alibaba.dubbo.common.utils.StringUtils;
-import com.alibaba.dubbo.config.*;
+import com.alibaba.dubbo.config.ApplicationConfig;
+import com.alibaba.dubbo.config.ConsumerConfig;
+import com.alibaba.dubbo.config.ProtocolConfig;
+import com.alibaba.dubbo.config.ProviderConfig;
+import com.alibaba.dubbo.config.ReferenceConfig;
+import com.alibaba.dubbo.config.RegistryConfig;
+import com.alibaba.dubbo.config.ServiceConfig;
 import com.alibaba.dubbo.config.spring.action.DemoActionByAnnotation;
 import com.alibaba.dubbo.config.spring.action.DemoActionBySetter;
 import com.alibaba.dubbo.config.spring.annotation.consumer.AnnotationAction;
@@ -49,7 +55,12 @@
 import java.util.Collection;
 import java.util.List;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import static org.junit.matchers.JUnitMatchers.containsString;
 
 
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 7766a1a602..327f4d91ba 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 @@
 /**
  * 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 0000000000..36def719d3
--- /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 0000000000..05a49807d4
--- /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 3f9a50e1af..01dbc5317d 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,20 @@
 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.After;
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 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 +44,27 @@
  */
 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 +114,66 @@ public void testGetReferenceBeans() {
 
     }
 
+    @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 +200,7 @@ public ApplicationContext getApplicationContext() {
 
     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 +212,7 @@ public DemoService getDemoServiceFromParent() {
 
     @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 +229,4 @@ public void setDemoService(DemoService demoService) {
         }
     }
 
-}
+}
\ 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 e5714c7f25..c096441814 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 @@
         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/annotation/EnableDubboConfigTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java
index 13f733da9b..1673be10ce 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java
@@ -16,7 +16,13 @@
  */
 package com.alibaba.dubbo.config.spring.context.annotation;
 
-import com.alibaba.dubbo.config.*;
+import com.alibaba.dubbo.config.ApplicationConfig;
+import com.alibaba.dubbo.config.ConsumerConfig;
+import com.alibaba.dubbo.config.ModuleConfig;
+import com.alibaba.dubbo.config.MonitorConfig;
+import com.alibaba.dubbo.config.ProtocolConfig;
+import com.alibaba.dubbo.config.ProviderConfig;
+import com.alibaba.dubbo.config.RegistryConfig;
 import org.junit.Assert;
 import org.junit.Test;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboTest.java
index 2020bed667..c5018da252 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboTest.java
@@ -24,7 +24,11 @@
 import org.junit.Assert;
 import org.junit.Test;
 import org.springframework.aop.support.AopUtils;
-import org.springframework.context.annotation.*;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Primary;
+import org.springframework.context.annotation.PropertySource;
 import org.springframework.transaction.PlatformTransactionManager;
 import org.springframework.transaction.TransactionDefinition;
 import org.springframework.transaction.TransactionException;
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 0000000000..f0ec69f505
--- /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/convert/converter/StringArrayToMapConverterTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToMapConverterTest.java
new file mode 100644
index 0000000000..51be7c3f2f
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToMapConverterTest.java
@@ -0,0 +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.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/convert/converter/StringArrayToStringConverterTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToStringConverterTest.java
new file mode 100644
index 0000000000..67e8247923
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/convert/converter/StringArrayToStringConverterTest.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.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);
+
+    }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/filter/MockFilter.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/filter/MockFilter.java
index de192b92e1..e4fc142a7c 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/filter/MockFilter.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/filter/MockFilter.java
@@ -16,7 +16,12 @@
  */
 package com.alibaba.dubbo.config.spring.filter;
 
-import com.alibaba.dubbo.rpc.*;
+import com.alibaba.dubbo.rpc.Filter;
+import com.alibaba.dubbo.rpc.Invocation;
+import com.alibaba.dubbo.rpc.Invoker;
+import com.alibaba.dubbo.rpc.Protocol;
+import com.alibaba.dubbo.rpc.Result;
+import com.alibaba.dubbo.rpc.RpcException;
 import com.alibaba.dubbo.rpc.cluster.LoadBalance;
 
 /**


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services