You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2019/07/02 02:17:30 UTC

[dubbo] branch 2.7.3-release updated: DubboComponentScan cannot backward support for alibaba @Service and @Reference. (#4415)

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

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


The following commit(s) were added to refs/heads/2.7.3-release by this push:
     new 60ca9f4   DubboComponentScan cannot backward support for alibaba @Service and @Reference. (#4415)
60ca9f4 is described below

commit 60ca9f4826ebb84ff41737c2ba2b60484eedc0f9
Author: Mercy Ma <me...@gmail.com>
AuthorDate: Tue Jul 2 10:17:12 2019 +0800

     DubboComponentScan cannot backward support for alibaba @Service and @Reference. (#4415)
    
    fixes #4330, #4409
---
 .../org/apache/dubbo/common/utils/PojoUtils.java   |   2 +-
 .../apache/dubbo/common/utils/PojoUtilsTest.java   |  19 +
 .../spring/context/annotation/EnableDubbo.java     |  12 +-
 ...atibleReferenceAnnotationBeanPostProcessor.java | 508 --------------------
 .../annotation/CompatibleReferenceBeanBuilder.java | 167 -------
 ...mpatibleServiceAnnotationBeanPostProcessor.java | 525 ---------------------
 .../annotation/CompatibleDubboComponentScan.java   |  66 ---
 .../CompatibleDubboComponentScanRegistrar.java     | 110 -----
 .../CompatibleAnnotationBeanDefinitionParser.java  |  93 ----
 .../AbstractAnnotationConfigBeanBuilder.java       |   3 +
 .../AnnotatedInterfaceConfigBeanBuilder.java       | 215 +++++++++
 .../AnnotationInjectedBeanPostProcessor.java       | 128 ++---
 .../AnnotationPropertyValuesAdapter.java           |  39 +-
 .../ReferenceAnnotationBeanPostProcessor.java      |  32 +-
 .../factory/annotation/ReferenceBeanBuilder.java   |  84 ++--
 .../ServiceAnnotationBeanPostProcessor.java        |   6 +-
 .../factory/annotation/ServiceBeanNameBuilder.java |   5 +-
 .../util/AnnotatedBeanDefinitionRegistryUtils.java |  62 ++-
 .../dubbo/config/spring/util/AnnotationUtils.java  | 135 ++++--
 .../dubbo/config/spring/util/BeanFactoryUtils.java |   6 +
 .../merged/MergedReference.java}                   |  35 +-
 .../merged/MergedService.java}                     |  33 +-
 .../factory/annotation/MergedAnnotationTest.java   |  76 +++
 .../ReferenceAnnotationBeanPostProcessorTest.java  |   2 +-
 .../annotation/provider/DefaultHelloService.java   |   4 +-
 .../AnnotatedBeanDefinitionRegistryUtilsTest.java  |  74 +++
 26 files changed, 749 insertions(+), 1692 deletions(-)

diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java
index 3bab261..52204ac 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java
@@ -366,7 +366,7 @@ public class PojoUtils {
                 history.put(pojo, dest);
                 for (Object obj : src) {
                     Type keyType = getGenericClassByIndex(genericType, 0);
-                    Class<?> keyClazz = obj.getClass();
+                    Class<?> keyClazz = obj == null ? null : obj.getClass();
                     if (keyType instanceof Class) {
                         keyClazz = (Class<?>) keyType;
                     }
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/PojoUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/PojoUtilsTest.java
index 3595efb..f0ab173 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/PojoUtilsTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/PojoUtilsTest.java
@@ -37,6 +37,7 @@ import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.UUID;
 
@@ -682,6 +683,24 @@ public class PojoUtilsTest {
         assertEquals(dateTimeStr, new SimpleDateFormat(dateFormat[0]).format(timestamp));
     }
 
+    @Test
+    public void testRealizeCollectionWithNullElement() {
+        LinkedList<String> listStr = new LinkedList<>();
+        listStr.add("arrayValue");
+        listStr.add(null);
+        HashSet<String> setStr = new HashSet<>();
+        setStr.add("setValue");
+        setStr.add(null);
+
+        Object listResult = PojoUtils.realize(listStr, LinkedList.class);
+        assertEquals(LinkedList.class, listResult.getClass());
+        assertEquals(listResult, listStr);
+
+        Object setResult = PojoUtils.realize(setStr, HashSet.class);
+        assertEquals(HashSet.class, setResult.getClass());
+        assertEquals(setResult, setStr);
+    }
+
     public enum Day {
         SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
     }
diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubbo.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubbo.java
index 1310d1a..d5227ed 100644
--- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubbo.java
+++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubbo.java
@@ -18,7 +18,7 @@
 package com.alibaba.dubbo.config.spring.context.annotation;
 
 import org.apache.dubbo.config.AbstractConfig;
-import org.apache.dubbo.config.spring.context.annotation.CompatibleDubboComponentScan;
+import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan;
 import org.apache.dubbo.config.spring.context.annotation.EnableDubboConfig;
 
 import org.springframework.core.annotation.AliasFor;
@@ -36,7 +36,7 @@ import java.lang.annotation.Target;
 @Inherited
 @Documented
 @EnableDubboConfig
-@CompatibleDubboComponentScan
+@DubboComponentScan
 public @interface EnableDubbo {
 
     /**
@@ -46,9 +46,9 @@ public @interface EnableDubbo {
      * package names.
      *
      * @return the base packages to scan
-     * @see CompatibleDubboComponentScan#basePackages()
+     * @see DubboComponentScan#basePackages()
      */
-    @AliasFor(annotation = CompatibleDubboComponentScan.class, attribute = "basePackages")
+    @AliasFor(annotation = DubboComponentScan.class, attribute = "basePackages")
     String[] scanBasePackages() default {};
 
     /**
@@ -57,9 +57,9 @@ public @interface EnableDubbo {
      * scanned.
      *
      * @return classes from the base packages to scan
-     * @see CompatibleDubboComponentScan#basePackageClasses
+     * @see DubboComponentScan#basePackageClasses
      */
-    @AliasFor(annotation = CompatibleDubboComponentScan.class, attribute = "basePackageClasses")
+    @AliasFor(annotation = DubboComponentScan.class, attribute = "basePackageClasses")
     Class<?>[] scanBasePackageClasses() default {};
 
 
diff --git a/dubbo-compatible/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/CompatibleReferenceAnnotationBeanPostProcessor.java b/dubbo-compatible/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/CompatibleReferenceAnnotationBeanPostProcessor.java
deleted file mode 100644
index d6826a5..0000000
--- a/dubbo-compatible/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/CompatibleReferenceAnnotationBeanPostProcessor.java
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.config.spring.beans.factory.annotation;
-
-import org.apache.dubbo.config.spring.ReferenceBean;
-
-import com.alibaba.dubbo.config.annotation.Reference;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.PropertyValues;
-import org.springframework.beans.factory.BeanClassLoaderAware;
-import org.springframework.beans.factory.BeanCreationException;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.annotation.InjectionMetadata;
-import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
-import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
-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;
-
-import java.beans.PropertyDescriptor;
-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;
-
-import static org.springframework.core.BridgeMethodResolver.findBridgedMethod;
-import static org.springframework.core.BridgeMethodResolver.isVisibilityBridgeMethodPair;
-import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
-import static org.springframework.core.annotation.AnnotationUtils.getAnnotation;
-
-/**
- * {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation
- * that Consumer service {@link Reference} annotated fields
- *
- * @since 2.5.7 deprecated since 2.7.0
- */
-@Deprecated
-public class CompatibleReferenceAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
-        implements MergedBeanDefinitionPostProcessor, PriorityOrdered, ApplicationContextAware, BeanClassLoaderAware,
-        DisposableBean {
-
-    /**
-     * The bean name of {@link CompatibleReferenceAnnotationBeanPostProcessor}
-     */
-    public static final String BEAN_NAME = "compatibleReferenceAnnotationBeanPostProcessor";
-
-    private final Log logger = LogFactory.getLog(getClass());
-
-    private ApplicationContext applicationContext;
-
-    private ClassLoader classLoader;
-
-    private final ConcurrentMap<String, ReferenceInjectionMetadata> injectionMetadataCache =
-            new ConcurrentHashMap<String, ReferenceInjectionMetadata>(256);
-
-    private final ConcurrentMap<String, ReferenceBean<?>> referenceBeansCache =
-            new ConcurrentHashMap<String, ReferenceBean<?>>();
-
-    @Override
-    public PropertyValues postProcessPropertyValues(
-            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
-
-        InjectionMetadata metadata = findReferenceMetadata(beanName, bean.getClass(), pvs);
-        try {
-            metadata.inject(bean, beanName, pvs);
-        } catch (BeanCreationException ex) {
-            throw ex;
-        } catch (Throwable ex) {
-            throw new BeanCreationException(beanName, "Injection of @Reference dependencies failed", ex);
-        }
-        return pvs;
-    }
-
-
-    /**
-     * Finds {@link InjectionMetadata.InjectedElement} Metadata from annotated {@link Reference @Reference} fields
-     *
-     * @param beanClass The {@link Class} of Bean
-     * @return non-null {@link List}
-     */
-    private List<ReferenceFieldElement> findFieldReferenceMetadata(final Class<?> beanClass) {
-
-        final List<ReferenceFieldElement> elements = new LinkedList<ReferenceFieldElement>();
-
-        ReflectionUtils.doWithFields(beanClass, new ReflectionUtils.FieldCallback() {
-            @Override
-            public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
-
-                Reference reference = getAnnotation(field, Reference.class);
-
-                if (reference != null) {
-
-                    if (Modifier.isStatic(field.getModifiers())) {
-                        if (logger.isWarnEnabled()) {
-                            logger.warn("@Reference annotation is not supported on static fields: " + field);
-                        }
-                        return;
-                    }
-
-                    elements.add(new ReferenceFieldElement(field, reference));
-                }
-
-            }
-        });
-
-        return elements;
-
-    }
-
-    /**
-     * Finds {@link InjectionMetadata.InjectedElement} Metadata from annotated {@link Reference @Reference} methods
-     *
-     * @param beanClass The {@link Class} of Bean
-     * @return non-null {@link List}
-     */
-    private List<ReferenceMethodElement> findMethodReferenceMetadata(final Class<?> beanClass) {
-
-        final List<ReferenceMethodElement> elements = new LinkedList<ReferenceMethodElement>();
-
-        ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {
-            @Override
-            public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
-
-                Method bridgedMethod = findBridgedMethod(method);
-
-                if (!isVisibilityBridgeMethodPair(method, bridgedMethod)) {
-                    return;
-                }
-
-                Reference reference = findAnnotation(bridgedMethod, Reference.class);
-
-                if (reference != null && method.equals(ClassUtils.getMostSpecificMethod(method, beanClass))) {
-                    if (Modifier.isStatic(method.getModifiers())) {
-                        if (logger.isWarnEnabled()) {
-                            logger.warn("@Reference annotation is not supported on static methods: " + method);
-                        }
-                        return;
-                    }
-                    if (method.getParameterTypes().length == 0) {
-                        if (logger.isWarnEnabled()) {
-                            logger.warn("@Reference  annotation should only be used on methods with parameters: " +
-                                    method);
-                        }
-                    }
-                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, beanClass);
-                    elements.add(new ReferenceMethodElement(method, pd, reference));
-                }
-            }
-        });
-
-        return elements;
-
-    }
-
-
-    /**
-     * @param beanClass
-     * @return
-     */
-    private ReferenceInjectionMetadata buildReferenceMetadata(final Class<?> beanClass) {
-        Collection<ReferenceFieldElement> fieldElements = findFieldReferenceMetadata(beanClass);
-        Collection<ReferenceMethodElement> methodElements = findMethodReferenceMetadata(beanClass);
-        return new ReferenceInjectionMetadata(beanClass, fieldElements, methodElements);
-
-    }
-
-    private InjectionMetadata findReferenceMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
-        // 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.
-        ReferenceInjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
-        if (InjectionMetadata.needsRefresh(metadata, clazz)) {
-            synchronized (this.injectionMetadataCache) {
-                metadata = this.injectionMetadataCache.get(cacheKey);
-                if (InjectionMetadata.needsRefresh(metadata, clazz)) {
-                    if (metadata != null) {
-                        metadata.clear(pvs);
-                    }
-                    try {
-                        metadata = buildReferenceMetadata(clazz);
-                        this.injectionMetadataCache.put(cacheKey, metadata);
-                    } catch (NoClassDefFoundError err) {
-                        throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() +
-                                "] for reference metadata: could not find class that it depends on", err);
-                    }
-                }
-            }
-        }
-        return metadata;
-    }
-
-    @Override
-    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-        this.applicationContext = applicationContext;
-    }
-
-    @Override
-    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
-        if (beanType != null) {
-            InjectionMetadata metadata = findReferenceMetadata(beanName, beanType, null);
-            metadata.checkConfigMembers(beanDefinition);
-        }
-    }
-
-    @Override
-    public int getOrder() {
-        return LOWEST_PRECEDENCE;
-    }
-
-    @Override
-    public void destroy() throws Exception {
-
-        for (ReferenceBean referenceBean : referenceBeansCache.values()) {
-            if (logger.isInfoEnabled()) {
-                logger.info(referenceBean + " was destroying!");
-            }
-            referenceBean.destroy();
-        }
-
-        injectionMetadataCache.clear();
-        referenceBeansCache.clear();
-
-        if (logger.isInfoEnabled()) {
-            logger.info(getClass() + " was destroying!");
-        }
-
-    }
-
-    @Override
-    public void setBeanClassLoader(ClassLoader classLoader) {
-        this.classLoader = classLoader;
-    }
-
-
-    /**
-     * Gets all beans of {@link ReferenceBean}
-     *
-     * @return non-null {@link Collection}
-     * @since 2.5.9
-     */
-    public Collection<ReferenceBean<?>> getReferenceBeans() {
-        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}
-     */
-    private class ReferenceMethodElement extends InjectionMetadata.InjectedElement {
-
-        private final Method method;
-
-        private final Reference reference;
-
-        private volatile ReferenceBean<?> referenceBean;
-
-        protected ReferenceMethodElement(Method method, PropertyDescriptor pd, Reference reference) {
-            super(method, pd);
-            this.method = method;
-            this.reference = reference;
-        }
-
-        @Override
-        protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
-
-            Class<?> referenceClass = pd.getPropertyType();
-
-            referenceBean = buildReferenceBean(reference, referenceClass);
-
-            ReflectionUtils.makeAccessible(method);
-
-            method.invoke(bean, referenceBean.getObject());
-
-        }
-
-    }
-
-    /**
-     * {@link Reference} {@link Field} {@link InjectionMetadata.InjectedElement}
-     */
-    private class ReferenceFieldElement extends InjectionMetadata.InjectedElement {
-
-        private final Field field;
-
-        private final Reference reference;
-
-        private volatile ReferenceBean<?> referenceBean;
-
-        protected ReferenceFieldElement(Field field, Reference reference) {
-            super(field, null);
-            this.field = field;
-            this.reference = reference;
-        }
-
-        @Override
-        protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
-
-            Class<?> referenceClass = field.getType();
-
-            referenceBean = buildReferenceBean(reference, referenceClass);
-
-            ReflectionUtils.makeAccessible(field);
-
-            field.set(bean, referenceBean.getObject());
-
-        }
-
-    }
-
-    private ReferenceBean<?> buildReferenceBean(Reference reference, Class<?> referenceClass) throws Exception {
-
-        String referenceBeanCacheKey = generateReferenceBeanCacheKey(reference, referenceClass);
-
-        ReferenceBean<?> referenceBean = referenceBeansCache.get(referenceBeanCacheKey);
-
-        if (referenceBean == null) {
-
-            CompatibleReferenceBeanBuilder beanBuilder = CompatibleReferenceBeanBuilder
-                    .create(reference, classLoader, applicationContext)
-                    .interfaceClass(referenceClass);
-
-            referenceBean = beanBuilder.build();
-
-            referenceBeansCache.putIfAbsent(referenceBeanCacheKey, referenceBean);
-
-        }
-
-        return referenceBean;
-
-    }
-
-
-    /**
-     * Generate a cache key of {@link ReferenceBean}
-     *
-     * @param reference {@link Reference}
-     * @param beanClass {@link Class}
-     * @return
-     */
-    private String generateReferenceBeanCacheKey(Reference reference, Class<?> beanClass) {
-
-        String interfaceName = resolveInterfaceName(reference, beanClass);
-
-        String key = reference.url() + "/" + interfaceName +
-                "/" + reference.version() +
-                "/" + reference.group();
-
-        Environment environment = applicationContext.getEnvironment();
-
-        key = environment.resolvePlaceholders(key);
-
-        return key;
-
-    }
-
-    private static String resolveInterfaceName(Reference reference, Class<?> beanClass)
-            throws IllegalStateException {
-
-        String interfaceName;
-        if (!"".equals(reference.interfaceName())) {
-            interfaceName = reference.interfaceName();
-        } else if (!void.class.equals(reference.interfaceClass())) {
-            interfaceName = reference.interfaceClass().getName();
-        } else if (beanClass.isInterface()) {
-            interfaceName = beanClass.getName();
-        } else {
-            throw new IllegalStateException(
-                    "The @Reference undefined interfaceClass or interfaceName, and the property type "
-                            + beanClass.getName() + " is not a interface.");
-        }
-
-        return interfaceName;
-
-    }
-
-
-    /**
-     * 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-compatible/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/CompatibleReferenceBeanBuilder.java b/dubbo-compatible/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/CompatibleReferenceBeanBuilder.java
deleted file mode 100644
index 16013b3..0000000
--- a/dubbo-compatible/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/CompatibleReferenceBeanBuilder.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.config.spring.beans.factory.annotation;
-
-import com.alibaba.dubbo.config.annotation.Reference;
-import org.apache.dubbo.common.utils.CollectionUtils;
-import org.apache.dubbo.config.ConsumerConfig;
-import org.apache.dubbo.config.spring.ReferenceBean;
-import org.springframework.beans.propertyeditors.StringTrimmerEditor;
-import org.springframework.context.ApplicationContext;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-import org.springframework.util.StringUtils;
-import org.springframework.validation.DataBinder;
-
-import java.beans.PropertyEditorSupport;
-import java.util.Map;
-
-import static org.apache.dubbo.config.spring.util.BeanFactoryUtils.getOptionalBean;
-import static org.apache.dubbo.config.spring.util.ObjectUtils.of;
-import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
-
-/**
- * {@link ReferenceBean} Builder
- *
- * @since 2.5.7 deprecated since 2.7.0
- */
-@Deprecated
-class CompatibleReferenceBeanBuilder extends AbstractAnnotationConfigBeanBuilder<Reference, ReferenceBean> {
-
-
-    // Ignore those fields
-    static final String[] IGNORE_FIELD_NAMES = of("application", "module", "consumer", "monitor", "registry");
-
-    private CompatibleReferenceBeanBuilder(Reference annotation, ClassLoader classLoader, ApplicationContext applicationContext) {
-        super(annotation, classLoader, applicationContext);
-    }
-
-    private void configureInterface(Reference reference, ReferenceBean referenceBean) {
-
-        Class<?> interfaceClass = reference.interfaceClass();
-
-        if (void.class.equals(interfaceClass)) {
-
-            interfaceClass = null;
-
-            String interfaceClassName = reference.interfaceName();
-
-            if (StringUtils.hasText(interfaceClassName)) {
-                if (ClassUtils.isPresent(interfaceClassName, classLoader)) {
-                    interfaceClass = ClassUtils.resolveClassName(interfaceClassName, classLoader);
-                }
-            }
-
-        }
-
-        if (interfaceClass == null) {
-            interfaceClass = this.interfaceClass;
-        }
-
-        Assert.isTrue(interfaceClass.isInterface(),
-                "The class of field or method that was annotated @Reference is not an interface!");
-
-        referenceBean.setInterface(interfaceClass);
-
-    }
-
-
-    private void configureConsumerConfig(Reference reference, ReferenceBean<?> referenceBean) {
-
-        String consumerBeanName = reference.consumer();
-
-        ConsumerConfig consumerConfig = getOptionalBean(applicationContext, consumerBeanName, ConsumerConfig.class);
-
-        referenceBean.setConsumer(consumerConfig);
-
-    }
-
-    @Override
-    protected ReferenceBean doBuild() {
-        return new ReferenceBean<Object>();
-    }
-
-    @Override
-    protected void preConfigureBean(Reference reference, ReferenceBean referenceBean) {
-        Assert.notNull(interfaceClass, "The interface class must set first!");
-        DataBinder dataBinder = new DataBinder(referenceBean);
-        // Register CustomEditors for special fields
-        dataBinder.registerCustomEditor(String.class, "filter", new StringTrimmerEditor(true));
-        dataBinder.registerCustomEditor(String.class, "listener", new StringTrimmerEditor(true));
-        dataBinder.registerCustomEditor(Map.class, "parameters", new PropertyEditorSupport() {
-            @Override
-            public void setAsText(String text) throws java.lang.IllegalArgumentException {
-                // Trim all whitespace
-                String content = StringUtils.trimAllWhitespace(text);
-                if (!StringUtils.hasText(content)) { // No content , ignore directly
-                    return;
-                }
-                // replace "=" to ","
-                content = StringUtils.replace(content, "=", ",");
-                // replace ":" to ","
-                content = StringUtils.replace(content, ":", ",");
-                // String[] to Map
-                Map<String, String> parameters = CollectionUtils.toStringMap(commaDelimitedListToStringArray(content));
-                setValue(parameters);
-            }
-        });
-
-        // Bind annotation attributes
-        dataBinder.bind(new AnnotationPropertyValuesAdapter(reference, applicationContext.getEnvironment(), IGNORE_FIELD_NAMES));
-
-    }
-
-
-    @Override
-    protected String resolveModuleConfigBeanName(Reference annotation) {
-        return annotation.module();
-    }
-
-    @Override
-    protected String resolveApplicationConfigBeanName(Reference annotation) {
-        return annotation.application();
-    }
-
-    @Override
-    protected String[] resolveRegistryConfigBeanNames(Reference annotation) {
-        return annotation.registry();
-    }
-
-    @Override
-    protected String resolveMonitorConfigBeanName(Reference annotation) {
-        return annotation.monitor();
-    }
-
-    @Override
-    protected void postConfigureBean(Reference annotation, ReferenceBean bean) throws Exception {
-
-        bean.setApplicationContext(applicationContext);
-
-        configureInterface(annotation, bean);
-
-        configureConsumerConfig(annotation, bean);
-
-        bean.afterPropertiesSet();
-
-    }
-
-    public static CompatibleReferenceBeanBuilder create(Reference annotation, ClassLoader classLoader,
-                                                        ApplicationContext applicationContext) {
-        return new CompatibleReferenceBeanBuilder(annotation, classLoader, applicationContext);
-    }
-
-}
diff --git a/dubbo-compatible/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/CompatibleServiceAnnotationBeanPostProcessor.java b/dubbo-compatible/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/CompatibleServiceAnnotationBeanPostProcessor.java
deleted file mode 100644
index 3d0370c..0000000
--- a/dubbo-compatible/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/CompatibleServiceAnnotationBeanPostProcessor.java
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.config.spring.beans.factory.annotation;
-
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.ArrayUtils;
-import org.apache.dubbo.config.spring.ServiceBean;
-import org.apache.dubbo.config.spring.context.annotation.DubboClassPathBeanDefinitionScanner;
-
-import com.alibaba.dubbo.config.annotation.Service;
-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.context.EnvironmentAware;
-import org.springframework.context.ResourceLoaderAware;
-import org.springframework.context.annotation.AnnotationBeanNameGenerator;
-import org.springframework.context.annotation.AnnotationConfigUtils;
-import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
-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.HashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static org.apache.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;
-import static org.springframework.util.ClassUtils.resolveClassName;
-
-/**
- * {@link Service} Annotation
- * {@link BeanDefinitionRegistryPostProcessor Bean Definition Registry Post Processor}
- *
- * @since 2.5.8 deprecated since 2.7.0
- */
-@Deprecated
-public class CompatibleServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware,
-        ResourceLoaderAware, BeanClassLoaderAware {
-
-    private static final String SEPARATOR = ":";
-
-    private final Logger logger = LoggerFactory.getLogger(getClass());
-
-    private final Set<String> packagesToScan;
-
-    private Environment environment;
-
-    private ResourceLoader resourceLoader;
-
-    private ClassLoader classLoader;
-
-    public CompatibleServiceAnnotationBeanPostProcessor(String... packagesToScan) {
-        this(Arrays.asList(packagesToScan));
-    }
-
-    public CompatibleServiceAnnotationBeanPostProcessor(Collection<String> packagesToScan) {
-        this(new LinkedHashSet<String>(packagesToScan));
-    }
-
-    public CompatibleServiceAnnotationBeanPostProcessor(Set<String> packagesToScan) {
-        this.packagesToScan = packagesToScan;
-    }
-
-    @Override
-    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
-
-        Set<String> resolvedPackagesToScan = resolvePackagesToScan(packagesToScan);
-
-        if (!CollectionUtils.isEmpty(resolvedPackagesToScan)) {
-            registerServiceBeans(resolvedPackagesToScan, registry);
-        } else {
-            if (logger.isWarnEnabled()) {
-                logger.warn("packagesToScan is empty , ServiceBean registry will be ignored!");
-            }
-        }
-
-    }
-
-
-    /**
-     * Registers Beans whose classes was annotated {@link Service}
-     *
-     * @param packagesToScan The base packages to scan
-     * @param registry       {@link BeanDefinitionRegistry}
-     */
-    private void registerServiceBeans(Set<String> packagesToScan, BeanDefinitionRegistry registry) {
-
-        DubboClassPathBeanDefinitionScanner scanner =
-                new DubboClassPathBeanDefinitionScanner(registry, environment, resourceLoader);
-
-        BeanNameGenerator beanNameGenerator = resolveBeanNameGenerator(registry);
-
-        scanner.setBeanNameGenerator(beanNameGenerator);
-
-        scanner.addIncludeFilter(new AnnotationTypeFilter(Service.class));
-
-        for (String packageToScan : packagesToScan) {
-
-            // Registers @Service Bean first
-            scanner.scan(packageToScan);
-
-            // Finds all BeanDefinitionHolders of @Service whether @ComponentScan scans or not.
-            Set<BeanDefinitionHolder> beanDefinitionHolders =
-                    findServiceBeanDefinitionHolders(scanner, packageToScan, registry, beanNameGenerator);
-
-            if (!CollectionUtils.isEmpty(beanDefinitionHolders)) {
-
-                for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
-                    registerServiceBean(beanDefinitionHolder, registry, scanner);
-                }
-
-                if (logger.isInfoEnabled()) {
-                    logger.info(beanDefinitionHolders.size() + " annotated Dubbo's @Service Components { " +
-                            beanDefinitionHolders +
-                            " } were scanned under package[" + packageToScan + "]");
-                }
-
-            } else {
-
-                if (logger.isWarnEnabled()) {
-                    logger.warn("No Spring Bean annotating Dubbo's @Service was found under package["
-                            + packageToScan + "]");
-                }
-
-            }
-
-        }
-
-    }
-
-    /**
-     * It'd better to use BeanNameGenerator instance that should reference
-     * {@link ConfigurationClassPostProcessor#componentScanBeanNameGenerator},
-     * thus it maybe a potential problem on bean name generation.
-     *
-     * @param registry {@link BeanDefinitionRegistry}
-     * @return {@link BeanNameGenerator} instance
-     * @see SingletonBeanRegistry
-     * @see AnnotationConfigUtils#CONFIGURATION_BEAN_NAME_GENERATOR
-     * @see ConfigurationClassPostProcessor#processConfigBeanDefinitions
-     * @since 2.5.8
-     */
-    private BeanNameGenerator resolveBeanNameGenerator(BeanDefinitionRegistry registry) {
-
-        BeanNameGenerator beanNameGenerator = null;
-
-        if (registry instanceof SingletonBeanRegistry) {
-            SingletonBeanRegistry singletonBeanRegistry = SingletonBeanRegistry.class.cast(registry);
-            beanNameGenerator = (BeanNameGenerator) singletonBeanRegistry.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
-        }
-
-        if (beanNameGenerator == null) {
-
-            if (logger.isInfoEnabled()) {
-
-                logger.info("BeanNameGenerator bean can't be found in BeanFactory with name ["
-                        + CONFIGURATION_BEAN_NAME_GENERATOR + "]");
-                logger.info("BeanNameGenerator will be a instance of " +
-                        AnnotationBeanNameGenerator.class.getName() +
-                        " , it maybe a potential problem on bean name generation.");
-            }
-
-            beanNameGenerator = new AnnotationBeanNameGenerator();
-
-        }
-
-        return beanNameGenerator;
-
-    }
-
-    /**
-     * Finds a {@link Set} of {@link BeanDefinitionHolder BeanDefinitionHolders} whose bean type annotated
-     * {@link Service} Annotation.
-     *
-     * @param scanner       {@link ClassPathBeanDefinitionScanner}
-     * @param packageToScan package to scan
-     * @param registry      {@link BeanDefinitionRegistry}
-     * @return non-null
-     * @since 2.5.8
-     */
-    private Set<BeanDefinitionHolder> findServiceBeanDefinitionHolders(
-            ClassPathBeanDefinitionScanner scanner, String packageToScan, BeanDefinitionRegistry registry,
-            BeanNameGenerator beanNameGenerator) {
-
-        Set<BeanDefinition> beanDefinitions = scanner.findCandidateComponents(packageToScan);
-
-        Set<BeanDefinitionHolder> beanDefinitionHolders = new LinkedHashSet<BeanDefinitionHolder>(beanDefinitions.size());
-
-        for (BeanDefinition beanDefinition : beanDefinitions) {
-
-            String beanName = beanNameGenerator.generateBeanName(beanDefinition, registry);
-            BeanDefinitionHolder beanDefinitionHolder = new BeanDefinitionHolder(beanDefinition, beanName);
-            beanDefinitionHolders.add(beanDefinitionHolder);
-
-        }
-
-        return beanDefinitionHolders;
-
-    }
-
-    /**
-     * Registers {@link ServiceBean} from new annotated {@link Service} {@link BeanDefinition}
-     *
-     * @param beanDefinitionHolder
-     * @param registry
-     * @param scanner
-     * @see ServiceBean
-     * @see BeanDefinition
-     */
-    private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, BeanDefinitionRegistry registry,
-                                     DubboClassPathBeanDefinitionScanner scanner) {
-
-        Class<?> beanClass = resolveClass(beanDefinitionHolder);
-
-        Service service = findAnnotation(beanClass, Service.class);
-
-        Class<?> interfaceClass = resolveServiceInterfaceClass(beanClass, service);
-
-        String annotatedServiceBeanName = beanDefinitionHolder.getBeanName();
-
-        AbstractBeanDefinition serviceBeanDefinition =
-                buildServiceBeanDefinition(service, interfaceClass, annotatedServiceBeanName);
-
-        // ServiceBean Bean name
-        String beanName = generateServiceBeanName(service, interfaceClass, annotatedServiceBeanName);
-
-        if (scanner.checkCandidate(beanName, serviceBeanDefinition)) { // check duplicated candidate bean
-            registry.registerBeanDefinition(beanName, serviceBeanDefinition);
-
-            if (logger.isInfoEnabled()) {
-                logger.warn("The BeanDefinition[" + serviceBeanDefinition +
-                        "] of ServiceBean has been registered with name : " + beanName);
-            }
-
-        } else {
-
-            if (logger.isWarnEnabled()) {
-                logger.warn("The Duplicated BeanDefinition[" + serviceBeanDefinition +
-                        "] of ServiceBean[ bean name : " + beanName +
-                        "] was be found , Did @CompatibleDubboComponentScan scan to same package in many times?");
-            }
-
-        }
-
-    }
-
-    /**
-     * 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(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);
-        }
-
-        String group = service.group();
-
-        if (StringUtils.hasText(group)) {
-            beanNameBuilder.append(SEPARATOR).append(group);
-        }
-
-        return beanNameBuilder.toString();
-
-    }
-
-    private Class<?> resolveServiceInterfaceClass(Class<?> annotatedServiceBeanClass, Service service) {
-
-        Class<?> interfaceClass = service.interfaceClass();
-
-        if (void.class.equals(interfaceClass)) {
-
-            interfaceClass = null;
-
-            String interfaceClassName = service.interfaceName();
-
-            if (StringUtils.hasText(interfaceClassName)) {
-                if (ClassUtils.isPresent(interfaceClassName, classLoader)) {
-                    interfaceClass = resolveClassName(interfaceClassName, classLoader);
-                }
-            }
-
-        }
-
-        if (interfaceClass == null) {
-
-            Class<?>[] allInterfaces = annotatedServiceBeanClass.getInterfaces();
-
-            if (allInterfaces.length > 0) {
-                interfaceClass = allInterfaces[0];
-            }
-
-        }
-
-        Assert.notNull(interfaceClass,
-                "@Service interfaceClass() or interfaceName() or interface class must be present!");
-
-        Assert.isTrue(interfaceClass.isInterface(),
-                "The type that was annotated @Service is not an interface!");
-
-        return interfaceClass;
-    }
-
-    private Class<?> resolveClass(BeanDefinitionHolder beanDefinitionHolder) {
-
-        BeanDefinition beanDefinition = beanDefinitionHolder.getBeanDefinition();
-
-        return resolveClass(beanDefinition);
-
-    }
-
-    private Class<?> resolveClass(BeanDefinition beanDefinition) {
-
-        String beanClassName = beanDefinition.getBeanClassName();
-
-        return resolveClassName(beanClassName, classLoader);
-
-    }
-
-    private Set<String> resolvePackagesToScan(Set<String> packagesToScan) {
-        Set<String> resolvedPackagesToScan = new LinkedHashSet<String>(packagesToScan.size());
-        for (String packageToScan : packagesToScan) {
-            if (StringUtils.hasText(packageToScan)) {
-                String resolvedPackageToScan = environment.resolvePlaceholders(packageToScan.trim());
-                resolvedPackagesToScan.add(resolvedPackageToScan);
-            }
-        }
-        return resolvedPackagesToScan;
-    }
-
-    private AbstractBeanDefinition buildServiceBeanDefinition(Service service, Class<?> interfaceClass,
-                                                              String annotatedServiceBeanName) {
-
-        BeanDefinitionBuilder builder = rootBeanDefinition(ServiceBean.class);
-
-        AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
-
-        MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
-
-        String[] ignoreAttributeNames = of("provider", "monitor", "application", "module", "registry", "protocol",
-                "interface", "parameters");
-
-        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());
-        // Convert parameters into map
-        builder.addPropertyValue("parameters", convertParameters(service.parameters()));
-
-        /**
-         * Add {@link org.apache.dubbo.config.ProviderConfig} Bean reference
-         */
-        String providerConfigBeanName = service.provider();
-        if (StringUtils.hasText(providerConfigBeanName)) {
-            addPropertyReference(builder, "provider", providerConfigBeanName);
-        }
-
-        /**
-         * Add {@link org.apache.dubbo.config.MonitorConfig} Bean reference
-         */
-        String monitorConfigBeanName = service.monitor();
-        if (StringUtils.hasText(monitorConfigBeanName)) {
-            addPropertyReference(builder, "monitor", monitorConfigBeanName);
-        }
-
-        /**
-         * Add {@link org.apache.dubbo.config.ApplicationConfig} Bean reference
-         */
-        String applicationConfigBeanName = service.application();
-        if (StringUtils.hasText(applicationConfigBeanName)) {
-            addPropertyReference(builder, "application", applicationConfigBeanName);
-        }
-
-        /**
-         * Add {@link org.apache.dubbo.config.ModuleConfig} Bean reference
-         */
-        String moduleConfigBeanName = service.module();
-        if (StringUtils.hasText(moduleConfigBeanName)) {
-            addPropertyReference(builder, "module", moduleConfigBeanName);
-        }
-
-
-        /**
-         * Add {@link org.apache.dubbo.config.RegistryConfig} Bean reference
-         */
-        String[] registryConfigBeanNames = service.registry();
-
-        List<RuntimeBeanReference> registryRuntimeBeanReferences = toRuntimeBeanReferences(registryConfigBeanNames);
-
-        if (!registryRuntimeBeanReferences.isEmpty()) {
-            builder.addPropertyValue("registries", registryRuntimeBeanReferences);
-        }
-
-        /**
-         * Add {@link org.apache.dubbo.config.ProtocolConfig} Bean reference
-         */
-        String[] protocolConfigBeanNames = service.protocol();
-
-        List<RuntimeBeanReference> protocolRuntimeBeanReferences = toRuntimeBeanReferences(protocolConfigBeanNames);
-
-        if (!protocolRuntimeBeanReferences.isEmpty()) {
-            builder.addPropertyValue("protocols", protocolRuntimeBeanReferences);
-        }
-
-        return builder.getBeanDefinition();
-
-    }
-
-
-    private ManagedList<RuntimeBeanReference> toRuntimeBeanReferences(String... beanNames) {
-
-        ManagedList<RuntimeBeanReference> runtimeBeanReferences = new ManagedList<RuntimeBeanReference>();
-
-        if (!ObjectUtils.isEmpty(beanNames)) {
-
-            for (String beanName : beanNames) {
-
-                String resolvedBeanName = environment.resolvePlaceholders(beanName);
-
-                runtimeBeanReferences.add(new RuntimeBeanReference(resolvedBeanName));
-            }
-
-        }
-
-        return runtimeBeanReferences;
-
-    }
-
-    private void addPropertyReference(BeanDefinitionBuilder builder, String propertyName, String beanName) {
-        String resolvedBeanName = environment.resolvePlaceholders(beanName);
-        builder.addPropertyReference(propertyName, resolvedBeanName);
-    }
-
-    private Map<String, String> convertParameters(String[] parameters) {
-        if (ArrayUtils.isEmpty(parameters)) {
-            return null;
-        }
-
-        if (parameters.length % 2 != 0) {
-            throw new IllegalArgumentException("parameter attribute must be paired with key followed by value");
-        }
-
-        Map<String, String> map = new HashMap<>();
-        for (int i = 0; i < parameters.length; i += 2) {
-            map.put(parameters[i], parameters[i + 1]);
-        }
-        return map;
-    }
-
-    @Override
-    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
-
-    }
-
-    @Override
-    public void setEnvironment(Environment environment) {
-        this.environment = environment;
-    }
-
-    @Override
-    public void setResourceLoader(ResourceLoader resourceLoader) {
-        this.resourceLoader = resourceLoader;
-    }
-
-    @Override
-    public void setBeanClassLoader(ClassLoader classLoader) {
-        this.classLoader = classLoader;
-    }
-}
diff --git a/dubbo-compatible/src/main/java/org/apache/dubbo/config/spring/context/annotation/CompatibleDubboComponentScan.java b/dubbo-compatible/src/main/java/org/apache/dubbo/config/spring/context/annotation/CompatibleDubboComponentScan.java
deleted file mode 100644
index 4b8e229..0000000
--- a/dubbo-compatible/src/main/java/org/apache/dubbo/config/spring/context/annotation/CompatibleDubboComponentScan.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.config.spring.context.annotation;
-
-import org.springframework.context.annotation.Import;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * @since 2.5.7 deprecated since 2.7.0
- */
-@Deprecated
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-@Import(CompatibleDubboComponentScanRegistrar.class)
-public @interface CompatibleDubboComponentScan {
-
-    /**
-     * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation
-     * declarations e.g.: {@code @CompatibleDubboComponentScan("org.my.pkg")} instead of
-     * {@code @CompatibleDubboComponentScan(basePackages="org.my.pkg")}.
-     *
-     * @return the base packages to scan
-     */
-    String[] value() default {};
-
-    /**
-     * Base packages to scan for annotated @Service classes. {@link #value()} is an
-     * alias for (and mutually exclusive with) this attribute.
-     * <p>
-     * Use {@link #basePackageClasses()} for a type-safe alternative to String-based
-     * package names.
-     *
-     * @return the base packages to scan
-     */
-    String[] basePackages() default {};
-
-    /**
-     * Type-safe alternative to {@link #basePackages()} for specifying the packages to
-     * scan for annotated @Service classes. The package of each class specified will be
-     * scanned.
-     *
-     * @return classes from the base packages to scan
-     */
-    Class<?>[] basePackageClasses() default {};
-
-}
diff --git a/dubbo-compatible/src/main/java/org/apache/dubbo/config/spring/context/annotation/CompatibleDubboComponentScanRegistrar.java b/dubbo-compatible/src/main/java/org/apache/dubbo/config/spring/context/annotation/CompatibleDubboComponentScanRegistrar.java
deleted file mode 100644
index 089bdda..0000000
--- a/dubbo-compatible/src/main/java/org/apache/dubbo/config/spring/context/annotation/CompatibleDubboComponentScanRegistrar.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.config.spring.context.annotation;
-
-import org.apache.dubbo.config.spring.beans.factory.annotation.CompatibleReferenceAnnotationBeanPostProcessor;
-import org.apache.dubbo.config.spring.beans.factory.annotation.CompatibleServiceAnnotationBeanPostProcessor;
-import org.apache.dubbo.config.spring.util.BeanRegistrar;
-
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
-import org.springframework.core.annotation.AnnotationAttributes;
-import org.springframework.core.type.AnnotationMetadata;
-import org.springframework.util.ClassUtils;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
-
-/**
- * Dubbo Bean Registrar
- * @see ImportBeanDefinitionRegistrar
- * @see CompatibleServiceAnnotationBeanPostProcessor
- * @see CompatibleReferenceAnnotationBeanPostProcessor
- * @since 2.5.7 deprecated since 2.7.0
- */
-@Deprecated
-public class CompatibleDubboComponentScanRegistrar implements ImportBeanDefinitionRegistrar {
-
-    @Override
-    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
-
-        Set<String> packagesToScan = getPackagesToScan(importingClassMetadata);
-
-        registerServiceAnnotationBeanPostProcessor(packagesToScan, registry);
-
-        registerReferenceAnnotationBeanPostProcessor(registry);
-
-    }
-
-    /**
-     * Registers {@link CompatibleServiceAnnotationBeanPostProcessor}
-     *
-     * @param packagesToScan packages to scan without resolving placeholders
-     * @param registry       {@link BeanDefinitionRegistry}
-     * @since 2.5.8 deprecated since 2.7.0
-     */
-    private void registerServiceAnnotationBeanPostProcessor(Set<String> packagesToScan, BeanDefinitionRegistry registry) {
-
-        BeanDefinitionBuilder builder = rootBeanDefinition(CompatibleServiceAnnotationBeanPostProcessor.class);
-        builder.addConstructorArgValue(packagesToScan);
-        builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
-        AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
-        BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, registry);
-
-    }
-
-    /**
-     * Registers {@link CompatibleReferenceAnnotationBeanPostProcessor} into {@link BeanFactory}
-     *
-     * @param registry {@link BeanDefinitionRegistry}
-     */
-    private void registerReferenceAnnotationBeanPostProcessor(BeanDefinitionRegistry registry) {
-
-        // Register @Reference Annotation Bean Processor
-        BeanRegistrar.registerInfrastructureBean(registry,
-                CompatibleReferenceAnnotationBeanPostProcessor.BEAN_NAME, CompatibleReferenceAnnotationBeanPostProcessor.class);
-
-    }
-
-    private Set<String> getPackagesToScan(AnnotationMetadata metadata) {
-        AnnotationAttributes attributes = AnnotationAttributes.fromMap(
-                metadata.getAnnotationAttributes(CompatibleDubboComponentScan.class.getName()));
-        String[] basePackages = attributes.getStringArray("basePackages");
-        Class<?>[] basePackageClasses = attributes.getClassArray("basePackageClasses");
-        String[] value = attributes.getStringArray("value");
-        // Appends value array attributes
-        Set<String> packagesToScan = new LinkedHashSet<String>(Arrays.asList(value));
-        packagesToScan.addAll(Arrays.asList(basePackages));
-        for (Class<?> basePackageClass : basePackageClasses) {
-            packagesToScan.add(ClassUtils.getPackageName(basePackageClass));
-        }
-        if (packagesToScan.isEmpty()) {
-            return Collections.singleton(ClassUtils.getPackageName(metadata.getClassName()));
-        }
-        return packagesToScan;
-    }
-
-}
diff --git a/dubbo-compatible/src/main/java/org/apache/dubbo/config/spring/schema/CompatibleAnnotationBeanDefinitionParser.java b/dubbo-compatible/src/main/java/org/apache/dubbo/config/spring/schema/CompatibleAnnotationBeanDefinitionParser.java
deleted file mode 100644
index 1172591..0000000
--- a/dubbo-compatible/src/main/java/org/apache/dubbo/config/spring/schema/CompatibleAnnotationBeanDefinitionParser.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.config.spring.schema;
-
-import org.apache.dubbo.config.spring.beans.factory.annotation.CompatibleReferenceAnnotationBeanPostProcessor;
-import org.apache.dubbo.config.spring.beans.factory.annotation.CompatibleServiceAnnotationBeanPostProcessor;
-import org.apache.dubbo.config.spring.util.BeanRegistrar;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
-import org.springframework.beans.factory.xml.BeanDefinitionParser;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.w3c.dom.Element;
-
-import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
-import static org.springframework.util.StringUtils.trimArrayElements;
-
-/**
- * {@link BeanDefinitionParser}
- *
- * @see CompatibleServiceAnnotationBeanPostProcessor
- * @see CompatibleReferenceAnnotationBeanPostProcessor
- * @since 2.5.9 deprecated since 2.7.0
- */
-@Deprecated
-public class CompatibleAnnotationBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
-
-    /**
-     * parse
-     * <prev>
-     * &lt;dubbo:annotation package="" /&gt;
-     * </prev>
-     *
-     * @param element
-     * @param parserContext
-     * @param builder
-     */
-    @Override
-    protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
-
-        String packageToScan = element.getAttribute("package");
-
-        String[] packagesToScan = trimArrayElements(commaDelimitedListToStringArray(packageToScan));
-
-        builder.addConstructorArgValue(packagesToScan);
-
-        builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
-
-        // Registers CompatibleReferenceAnnotationBeanPostProcessor
-        registerReferenceAnnotationBeanPostProcessor(parserContext.getRegistry());
-
-    }
-
-    @Override
-    protected boolean shouldGenerateIdAsFallback() {
-        return true;
-    }
-
-    /**
-     * Registers {@link CompatibleReferenceAnnotationBeanPostProcessor} into {@link BeanFactory}
-     *
-     * @param registry {@link BeanDefinitionRegistry}
-     */
-    private void registerReferenceAnnotationBeanPostProcessor(BeanDefinitionRegistry registry) {
-
-        // Register @Reference Annotation Bean Processor
-        BeanRegistrar.registerInfrastructureBean(registry,
-                CompatibleReferenceAnnotationBeanPostProcessor.BEAN_NAME, CompatibleReferenceAnnotationBeanPostProcessor.class);
-
-    }
-
-    @Override
-    protected Class<?> getBeanClass(Element element) {
-        return CompatibleServiceAnnotationBeanPostProcessor.class;
-    }
-
-}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AbstractAnnotationConfigBeanBuilder.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AbstractAnnotationConfigBeanBuilder.java
index 7f7afd9..25da5d9 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AbstractAnnotationConfigBeanBuilder.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AbstractAnnotationConfigBeanBuilder.java
@@ -35,8 +35,11 @@ import static org.apache.dubbo.config.spring.util.BeanFactoryUtils.getOptionalBe
 
 /**
  * Abstract Configurable {@link Annotation} Bean Builder
+ *
  * @since 2.5.7
+ * @deprecated use {@link AnnotatedInterfaceConfigBeanBuilder}
  */
+@Deprecated
 abstract class AbstractAnnotationConfigBeanBuilder<A extends Annotation, B extends AbstractInterfaceConfig> {
 
     protected final Log logger = LogFactory.getLog(getClass());
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotatedInterfaceConfigBeanBuilder.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotatedInterfaceConfigBeanBuilder.java
new file mode 100644
index 0000000..32a37ba
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotatedInterfaceConfigBeanBuilder.java
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.config.spring.beans.factory.annotation;
+
+import org.apache.dubbo.config.AbstractInterfaceConfig;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ModuleConfig;
+import org.apache.dubbo.config.MonitorConfig;
+import org.apache.dubbo.config.RegistryConfig;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.annotation.AnnotationAttributes;
+import org.springframework.util.Assert;
+
+import java.lang.annotation.Annotation;
+import java.util.List;
+
+import static org.apache.dubbo.config.spring.util.BeanFactoryUtils.getBeans;
+import static org.apache.dubbo.config.spring.util.BeanFactoryUtils.getOptionalBean;
+
+/**
+ * An Abstract Builder to build {@link AbstractInterfaceConfig Interface Config} Bean that annotated
+ * some {@link Annotation annotation}.
+ *
+ * @see ReferenceBeanBuilder
+ * @see AbstractInterfaceConfig
+ * @see AnnotationAttributes
+ * @since 2.7.3
+ */
+public abstract class AnnotatedInterfaceConfigBeanBuilder<C extends AbstractInterfaceConfig> {
+
+    protected final Log logger = LogFactory.getLog(getClass());
+
+    protected final AnnotationAttributes attributes;
+
+    protected final ApplicationContext applicationContext;
+
+    protected final ClassLoader classLoader;
+
+    protected Object configBean;
+
+    protected Class<?> interfaceClass;
+
+    protected AnnotatedInterfaceConfigBeanBuilder(AnnotationAttributes attributes, ApplicationContext applicationContext) {
+        Assert.notNull(attributes, "The Annotation attributes must not be null!");
+        Assert.notNull(applicationContext, "The ApplicationContext must not be null!");
+        this.attributes = attributes;
+        this.applicationContext = applicationContext;
+        this.classLoader = applicationContext.getClassLoader() != null ?
+                applicationContext.getClassLoader() : Thread.currentThread().getContextClassLoader();
+    }
+
+    /**
+     * Build {@link C}
+     *
+     * @return non-null
+     * @throws Exception
+     */
+    public final C build() throws Exception {
+
+        checkDependencies();
+
+        C configBean = doBuild();
+
+        configureBean(configBean);
+
+        if (logger.isInfoEnabled()) {
+            logger.info("The configBean[type:" + configBean.getClass().getSimpleName() + "] has been built.");
+        }
+
+        return configBean;
+
+    }
+
+    private void checkDependencies() {
+
+    }
+
+    /**
+     * Builds {@link C Bean}
+     *
+     * @return {@link C Bean}
+     */
+    protected abstract C doBuild();
+
+
+    protected void configureBean(C configBean) throws Exception {
+
+        preConfigureBean(attributes, configBean);
+
+        configureRegistryConfigs(configBean);
+
+        configureMonitorConfig(configBean);
+
+        configureApplicationConfig(configBean);
+
+        configureModuleConfig(configBean);
+
+        postConfigureBean(attributes, configBean);
+
+    }
+
+    protected abstract void preConfigureBean(AnnotationAttributes attributes, C configBean) throws Exception;
+
+
+    private void configureRegistryConfigs(C configBean) {
+
+        String[] registryConfigBeanIds = resolveRegistryConfigBeanNames(attributes);
+
+        List<RegistryConfig> registryConfigs = getBeans(applicationContext, registryConfigBeanIds, RegistryConfig.class);
+
+        configBean.setRegistries(registryConfigs);
+
+    }
+
+    private void configureMonitorConfig(C configBean) {
+
+        String monitorBeanName = resolveMonitorConfigBeanName(attributes);
+
+        MonitorConfig monitorConfig = getOptionalBean(applicationContext, monitorBeanName, MonitorConfig.class);
+
+        configBean.setMonitor(monitorConfig);
+
+    }
+
+    private void configureApplicationConfig(C configBean) {
+
+        String applicationConfigBeanName = resolveApplicationConfigBeanName(attributes);
+
+        ApplicationConfig applicationConfig =
+                getOptionalBean(applicationContext, applicationConfigBeanName, ApplicationConfig.class);
+
+        configBean.setApplication(applicationConfig);
+
+    }
+
+    private void configureModuleConfig(C configBean) {
+
+        String moduleConfigBeanName = resolveModuleConfigBeanName(attributes);
+
+        ModuleConfig moduleConfig =
+                getOptionalBean(applicationContext, moduleConfigBeanName, ModuleConfig.class);
+
+        configBean.setModule(moduleConfig);
+
+    }
+
+    /**
+     * Resolves the configBean name of {@link ModuleConfig}
+     *
+     * @param attributes {@link AnnotationAttributes}
+     * @return
+     */
+    protected abstract String resolveModuleConfigBeanName(AnnotationAttributes attributes);
+
+    /**
+     * Resolves the configBean name of {@link ApplicationConfig}
+     *
+     * @param attributes {@link AnnotationAttributes}
+     * @return
+     */
+    protected abstract String resolveApplicationConfigBeanName(AnnotationAttributes attributes);
+
+
+    /**
+     * Resolves the configBean ids of {@link RegistryConfig}
+     *
+     * @param attributes {@link AnnotationAttributes}
+     * @return non-empty array
+     */
+    protected abstract String[] resolveRegistryConfigBeanNames(AnnotationAttributes attributes);
+
+    /**
+     * Resolves the configBean name of {@link MonitorConfig}
+     *
+     * @param attributes {@link AnnotationAttributes}
+     * @return
+     */
+    protected abstract String resolveMonitorConfigBeanName(AnnotationAttributes attributes);
+
+    /**
+     * Configures Bean
+     *
+     * @param attributes
+     * @param configBean
+     */
+    protected abstract void postConfigureBean(AnnotationAttributes attributes, C configBean) throws Exception;
+
+
+    public <T extends AnnotatedInterfaceConfigBeanBuilder<C>> T configBean(Object configBean) {
+        this.configBean = configBean;
+        return (T) this;
+    }
+
+    public <T extends AnnotatedInterfaceConfigBeanBuilder<C>> T interfaceClass(Class<?> interfaceClass) {
+        this.interfaceClass = interfaceClass;
+        return (T) this;
+    }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationInjectedBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationInjectedBeanPostProcessor.java
index 53ff695..de56d29 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationInjectedBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationInjectedBeanPostProcessor.java
@@ -35,6 +35,7 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
 import org.springframework.context.EnvironmentAware;
 import org.springframework.core.Ordered;
 import org.springframework.core.PriorityOrdered;
+import org.springframework.core.annotation.AnnotationAttributes;
 import org.springframework.core.env.Environment;
 import org.springframework.util.Assert;
 import org.springframework.util.ClassUtils;
@@ -56,20 +57,20 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
-import static org.apache.dubbo.config.spring.util.ClassUtils.resolveGenericType;
+import static org.apache.dubbo.config.spring.util.AnnotationUtils.getMergedAttributes;
 import static org.springframework.core.BridgeMethodResolver.findBridgedMethod;
 import static org.springframework.core.BridgeMethodResolver.isVisibilityBridgeMethodPair;
-import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
-import static org.springframework.core.annotation.AnnotationUtils.getAnnotation;
+import static org.springframework.util.CollectionUtils.isEmpty;
 
 /**
  * Abstract generic {@link BeanPostProcessor} implementation for customized annotation that annotated injected-object.
- *
+ * <p>
  * The source code is cloned from https://github.com/alibaba/spring-context-support/blob/1.0.2/src/main/java/com/alibaba/spring/beans/factory/annotation/AnnotationInjectedBeanPostProcessor.java
  *
+ * @revision 2.7.3 Uses {@link AnnotationAttributes} instead of {@link Annotation}
  * @since 2.6.6
  */
-public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation> extends
+public abstract class AnnotationInjectedBeanPostProcessor extends
         InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor, PriorityOrdered,
         BeanFactoryAware, BeanClassLoaderAware, EnvironmentAware, DisposableBean {
 
@@ -77,7 +78,7 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
 
     private final Log logger = LogFactory.getLog(getClass());
 
-    private final Class<A> annotationType;
+    private final Class<? extends Annotation>[] annotationTypes;
 
     private final ConcurrentMap<String, AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata> injectionMetadataCache =
             new ConcurrentHashMap<String, AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata>(CACHE_SIZE);
@@ -92,8 +93,13 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
 
     private int order = Ordered.LOWEST_PRECEDENCE;
 
-    public AnnotationInjectedBeanPostProcessor() {
-        this.annotationType = resolveGenericType(getClass());
+    /**
+     * @param annotationTypes the multiple types of {@link Annotation annotations}
+     * @since 2.7.3
+     */
+    public AnnotationInjectedBeanPostProcessor(Class<? extends Annotation>... annotationTypes) {
+        Assert.notEmpty(annotationTypes, "The argument of annotations' types must not empty");
+        this.annotationTypes = annotationTypes;
     }
 
     @SafeVarargs
@@ -109,9 +115,15 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
      * Annotation type
      *
      * @return non-null
+     * @deprecated 2.7.3, uses {@link #getAnnotationTypes()}
      */
-    public final Class<A> getAnnotationType() {
-        return annotationType;
+    @Deprecated
+    public final Class<? extends Annotation> getAnnotationType() {
+        return annotationTypes[0];
+    }
+
+    protected final Class<? extends Annotation>[] getAnnotationTypes() {
+        return annotationTypes;
     }
 
     @Override
@@ -131,7 +143,7 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
         } catch (BeanCreationException ex) {
             throw ex;
         } catch (Throwable ex) {
-            throw new BeanCreationException(beanName, "Injection of @" + getAnnotationType().getName()
+            throw new BeanCreationException(beanName, "Injection of @" + getAnnotationType().getSimpleName()
                     + " dependencies is failed", ex);
         }
         return pvs;
@@ -139,7 +151,7 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
 
 
     /**
-     * Finds {@link InjectionMetadata.InjectedElement} Metadata from annotated {@link A} fields
+     * Finds {@link InjectionMetadata.InjectedElement} Metadata from annotated fields
      *
      * @param beanClass The {@link Class} of Bean
      * @return non-null {@link List}
@@ -150,20 +162,22 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
 
         ReflectionUtils.doWithFields(beanClass, field -> {
 
-            A annotation = getAnnotation(field, getAnnotationType());
+            for (Class<? extends Annotation> annotationType : getAnnotationTypes()) {
+
+                AnnotationAttributes attributes = getMergedAttributes(field, annotationType, getEnvironment(), true);
 
-            if (annotation != null) {
+                if (!isEmpty(attributes)) {
 
-                if (Modifier.isStatic(field.getModifiers())) {
-                    if (logger.isWarnEnabled()) {
-                        logger.warn("@" + getAnnotationType().getName() + " is not supported on static fields: " + field);
+                    if (Modifier.isStatic(field.getModifiers())) {
+                        if (logger.isWarnEnabled()) {
+                            logger.warn("@" + annotationType.getName() + " is not supported on static fields: " + field);
+                        }
+                        return;
                     }
-                    return;
-                }
 
-                elements.add(new AnnotatedFieldElement(field, annotation));
+                    elements.add(new AnnotatedFieldElement(field, attributes));
+                }
             }
-
         });
 
         return elements;
@@ -171,7 +185,7 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
     }
 
     /**
-     * Finds {@link InjectionMetadata.InjectedElement} Metadata from annotated {@link A @A} methods
+     * Finds {@link InjectionMetadata.InjectedElement} Metadata from annotated methods
      *
      * @param beanClass The {@link Class} of Bean
      * @return non-null {@link List}
@@ -188,23 +202,27 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
                 return;
             }
 
-            A annotation = findAnnotation(bridgedMethod, getAnnotationType());
 
-            if (annotation != null && method.equals(ClassUtils.getMostSpecificMethod(method, beanClass))) {
-                if (Modifier.isStatic(method.getModifiers())) {
-                    if (logger.isWarnEnabled()) {
-                        logger.warn("@" + getAnnotationType().getSimpleName() + " annotation is not supported on static methods: " + method);
+            for (Class<? extends Annotation> annotationType : getAnnotationTypes()) {
+
+                AnnotationAttributes attributes = getMergedAttributes(bridgedMethod, annotationType, getEnvironment(), true);
+
+                if (!isEmpty(attributes) && method.equals(ClassUtils.getMostSpecificMethod(method, beanClass))) {
+                    if (Modifier.isStatic(method.getModifiers())) {
+                        if (logger.isWarnEnabled()) {
+                            logger.warn("@" + annotationType.getName() + " annotation is not supported on static methods: " + method);
+                        }
+                        return;
                     }
-                    return;
-                }
-                if (method.getParameterTypes().length == 0) {
-                    if (logger.isWarnEnabled()) {
-                        logger.warn("@" + getAnnotationType().getSimpleName() + " annotation should only be used on methods with parameters: " +
-                                method);
+                    if (method.getParameterTypes().length == 0) {
+                        if (logger.isWarnEnabled()) {
+                            logger.warn("@" + annotationType.getName() + " annotation should only be used on methods with parameters: " +
+                                    method);
+                        }
                     }
+                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, beanClass);
+                    elements.add(new AnnotatedMethodElement(method, pd, attributes));
                 }
-                PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, beanClass);
-                elements.add(new AnnotatedMethodElement(method, pd, annotation));
             }
         });
 
@@ -316,9 +334,9 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
     }
 
     /**
-     * Get injected-object from specified {@link A annotation} and Bean Class
+     * Get injected-object from specified {@link AnnotationAttributes annotation attributes} and Bean Class
      *
-     * @param annotation      {@link A annotation}
+     * @param attributes      {@link AnnotationAttributes the annotation attributes}
      * @param bean            Current bean that will be injected
      * @param beanName        Current bean name that will be injected
      * @param injectedType    the type of injected-object
@@ -326,15 +344,15 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
      * @return An injected object
      * @throws Exception If getting is failed
      */
-    protected Object getInjectedObject(A annotation, Object bean, String beanName, Class<?> injectedType,
+    protected Object getInjectedObject(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType,
                                        InjectionMetadata.InjectedElement injectedElement) throws Exception {
 
-        String cacheKey = buildInjectedObjectCacheKey(annotation, bean, beanName, injectedType, injectedElement);
+        String cacheKey = buildInjectedObjectCacheKey(attributes, bean, beanName, injectedType, injectedElement);
 
         Object injectedObject = injectedObjectsCache.get(cacheKey);
 
         if (injectedObject == null) {
-            injectedObject = doGetInjectedBean(annotation, bean, beanName, injectedType, injectedElement);
+            injectedObject = doGetInjectedBean(attributes, bean, beanName, injectedType, injectedElement);
             // Customized inject-object if necessary
             injectedObjectsCache.putIfAbsent(cacheKey, injectedObject);
         }
@@ -352,7 +370,7 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
      * <li>{@link #getEnvironment() Environment}</li>
      * </ul>
      *
-     * @param annotation      {@link A annotation}
+     * @param attributes      {@link AnnotationAttributes the annotation attributes}
      * @param bean            Current bean that will be injected
      * @param beanName        Current bean name that will be injected
      * @param injectedType    the type of injected-object
@@ -360,7 +378,7 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
      * @return The injected object
      * @throws Exception If resolving an injected object is failed.
      */
-    protected abstract Object doGetInjectedBean(A annotation, Object bean, String beanName, Class<?> injectedType,
+    protected abstract Object doGetInjectedBean(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType,
                                                 InjectionMetadata.InjectedElement injectedElement) throws Exception;
 
     /**
@@ -372,14 +390,14 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
      * <li>{@link #getEnvironment() Environment}</li>
      * </ul>
      *
-     * @param annotation      {@link A annotation}
+     * @param attributes      {@link AnnotationAttributes the annotation attributes}
      * @param bean            Current bean that will be injected
      * @param beanName        Current bean name that will be injected
      * @param injectedType    the type of injected-object
      * @param injectedElement {@link InjectionMetadata.InjectedElement}
      * @return Bean cache key
      */
-    protected abstract String buildInjectedObjectCacheKey(A annotation, Object bean, String beanName,
+    protected abstract String buildInjectedObjectCacheKey(AnnotationAttributes attributes, Object bean, String beanName,
                                                           Class<?> injectedType,
                                                           InjectionMetadata.InjectedElement injectedElement);
 
@@ -436,7 +454,7 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
     }
 
     /**
-     * {@link A} {@link InjectionMetadata} implementation
+     * {@link Annotation Annotated} {@link InjectionMetadata} implementation
      */
     private class AnnotatedInjectionMetadata extends InjectionMetadata {
 
@@ -461,20 +479,20 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
     }
 
     /**
-     * {@link A} {@link Method} {@link InjectionMetadata.InjectedElement}
+     * {@link Annotation Annotated} {@link Method} {@link InjectionMetadata.InjectedElement}
      */
     private class AnnotatedMethodElement extends InjectionMetadata.InjectedElement {
 
         private final Method method;
 
-        private final A annotation;
+        private final AnnotationAttributes attributes;
 
         private volatile Object object;
 
-        protected AnnotatedMethodElement(Method method, PropertyDescriptor pd, A annotation) {
+        protected AnnotatedMethodElement(Method method, PropertyDescriptor pd, AnnotationAttributes attributes) {
             super(method, pd);
             this.method = method;
-            this.annotation = annotation;
+            this.attributes = attributes;
         }
 
         @Override
@@ -482,7 +500,7 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
 
             Class<?> injectedType = pd.getPropertyType();
 
-            Object injectedObject = getInjectedObject(annotation, bean, beanName, injectedType, this);
+            Object injectedObject = getInjectedObject(attributes, bean, beanName, injectedType, this);
 
             ReflectionUtils.makeAccessible(method);
 
@@ -493,20 +511,20 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
     }
 
     /**
-     * {@link A} {@link Field} {@link InjectionMetadata.InjectedElement}
+     * {@link Annotation Annotated} {@link Field} {@link InjectionMetadata.InjectedElement}
      */
     public class AnnotatedFieldElement extends InjectionMetadata.InjectedElement {
 
         private final Field field;
 
-        private final A annotation;
+        private final AnnotationAttributes attributes;
 
         private volatile Object bean;
 
-        protected AnnotatedFieldElement(Field field, A annotation) {
+        protected AnnotatedFieldElement(Field field, AnnotationAttributes attributes) {
             super(field, null);
             this.field = field;
-            this.annotation = annotation;
+            this.attributes = attributes;
         }
 
         @Override
@@ -514,7 +532,7 @@ public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation>
 
             Class<?> injectedType = field.getType();
 
-            Object injectedObject = getInjectedObject(annotation, bean, beanName, injectedType, this);
+            Object injectedObject = getInjectedObject(attributes, bean, beanName, injectedType, this);
 
             ReflectionUtils.makeAccessible(field);
 
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java
index b051d35..5566c39 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java
@@ -22,8 +22,10 @@ import org.springframework.beans.PropertyValues;
 import org.springframework.core.env.PropertyResolver;
 
 import java.lang.annotation.Annotation;
+import java.util.Map;
 
 import static org.apache.dubbo.config.spring.util.AnnotationUtils.getAttributes;
+import static org.apache.dubbo.config.spring.util.AnnotationUtils.resolvePlaceholders;
 
 /**
  * {@link Annotation} {@link PropertyValues} Adapter
@@ -34,35 +36,26 @@ import static org.apache.dubbo.config.spring.util.AnnotationUtils.getAttributes;
  */
 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);
+    /**
+     * @param attributes
+     * @param propertyResolver
+     * @param ignoreAttributeNames
+     * @since 2.7.3
+     */
+    public AnnotationPropertyValuesAdapter(Map<String, Object> attributes, PropertyResolver propertyResolver,
+                                           String... ignoreAttributeNames) {
+        this.delegate = new MutablePropertyValues(resolvePlaceholders(attributes, propertyResolver, ignoreAttributeNames));
     }
 
-    public AnnotationPropertyValuesAdapter(Annotation annotation, PropertyResolver propertyResolver, String... ignoreAttributeNames) {
-        this(annotation, propertyResolver, true, ignoreAttributeNames);
+    public AnnotationPropertyValuesAdapter(Annotation annotation, PropertyResolver propertyResolver,
+                                           boolean ignoreDefaultValue, String... ignoreAttributeNames) {
+        this.delegate = new MutablePropertyValues(getAttributes(annotation, propertyResolver, ignoreDefaultValue, 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;
+    public AnnotationPropertyValuesAdapter(Annotation annotation, PropertyResolver propertyResolver, String... ignoreAttributeNames) {
+        this(annotation, propertyResolver, true, ignoreAttributeNames);
     }
 
     @Override
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
index f7cc7b7..d477c58 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
@@ -29,6 +29,7 @@ import org.springframework.context.ApplicationContextAware;
 import org.springframework.context.ApplicationEvent;
 import org.springframework.context.ApplicationListener;
 import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.core.annotation.AnnotationAttributes;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationHandler;
@@ -49,8 +50,8 @@ import static org.apache.dubbo.config.spring.beans.factory.annotation.ServiceBea
  *
  * @since 2.5.7
  */
-public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBeanPostProcessor<Reference>
-        implements ApplicationContextAware, ApplicationListener {
+public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBeanPostProcessor implements
+        ApplicationContextAware, ApplicationListener {
 
     /**
      * The bean name of {@link ReferenceAnnotationBeanPostProcessor}
@@ -77,6 +78,13 @@ public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBean
     private ApplicationContext applicationContext;
 
     /**
+     * To support the legacy annotation that is @com.alibaba.dubbo.config.annotation.Reference since 2.7.3
+     */
+    public ReferenceAnnotationBeanPostProcessor() {
+        super(Reference.class, com.alibaba.dubbo.config.annotation.Reference.class);
+    }
+
+    /**
      * Gets all beans of {@link ReferenceBean}
      *
      * @return non-null read-only {@link Collection}
@@ -107,12 +115,12 @@ public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBean
     }
 
     @Override
-    protected Object doGetInjectedBean(Reference reference, Object bean, String beanName, Class<?> injectedType,
+    protected Object doGetInjectedBean(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType,
                                        InjectionMetadata.InjectedElement injectedElement) throws Exception {
 
-        String referencedBeanName = buildReferencedBeanName(reference, injectedType);
+        String referencedBeanName = buildReferencedBeanName(attributes, injectedType);
 
-        ReferenceBean referenceBean = buildReferenceBeanIfAbsent(referencedBeanName, reference, injectedType, getClassLoader());
+        ReferenceBean referenceBean = buildReferenceBeanIfAbsent(referencedBeanName, attributes, injectedType, getClassLoader());
 
         cacheInjectedReferenceBean(referenceBean, injectedElement);
 
@@ -175,22 +183,22 @@ public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBean
     }
 
     @Override
-    protected String buildInjectedObjectCacheKey(Reference reference, Object bean, String beanName,
+    protected String buildInjectedObjectCacheKey(AnnotationAttributes attributes, Object bean, String beanName,
                                                  Class<?> injectedType, InjectionMetadata.InjectedElement injectedElement) {
 
-        return buildReferencedBeanName(reference, injectedType) +
+        return buildReferencedBeanName(attributes, injectedType) +
                 "#source=" + (injectedElement.getMember()) +
-                "#attributes=" + AnnotationUtils.getAttributes(reference, getEnvironment(), true);
+                "#attributes=" + AnnotationUtils.resolvePlaceholders(attributes, getEnvironment());
     }
 
-    private String buildReferencedBeanName(Reference reference, Class<?> injectedType) {
+    private String buildReferencedBeanName(AnnotationAttributes attributes, Class<?> injectedType) {
 
-        ServiceBeanNameBuilder serviceBeanNameBuilder = create(reference, injectedType, getEnvironment());
+        ServiceBeanNameBuilder serviceBeanNameBuilder = create(attributes, injectedType, getEnvironment());
 
         return serviceBeanNameBuilder.build();
     }
 
-    private ReferenceBean buildReferenceBeanIfAbsent(String referencedBeanName, Reference reference,
+    private ReferenceBean buildReferenceBeanIfAbsent(String referencedBeanName, AnnotationAttributes attributes,
                                                      Class<?> referencedType, ClassLoader classLoader)
             throws Exception {
 
@@ -198,7 +206,7 @@ public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBean
 
         if (referenceBean == null) {
             ReferenceBeanBuilder beanBuilder = ReferenceBeanBuilder
-                    .create(reference, classLoader, applicationContext)
+                    .create(attributes, applicationContext)
                     .interfaceClass(referencedType);
             referenceBean = beanBuilder.build();
             referenceBeanCache.put(referencedBeanName, referenceBean);
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java
index d4aef6a..2054473 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java
@@ -25,8 +25,8 @@ import org.apache.dubbo.config.spring.ReferenceBean;
 
 import org.springframework.beans.propertyeditors.StringTrimmerEditor;
 import org.springframework.context.ApplicationContext;
+import org.springframework.core.annotation.AnnotationAttributes;
 import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
 import org.springframework.util.StringUtils;
 import org.springframework.validation.DataBinder;
 
@@ -34,8 +34,12 @@ import java.beans.PropertyEditorSupport;
 import java.util.List;
 import java.util.Map;
 
+import static org.apache.dubbo.config.spring.util.AnnotationUtils.getAttribute;
+import static org.apache.dubbo.config.spring.util.AnnotationUtils.getAttributes;
+import static org.apache.dubbo.config.spring.util.AnnotationUtils.resolveServiceInterfaceClass;
 import static org.apache.dubbo.config.spring.util.BeanFactoryUtils.getOptionalBean;
 import static org.apache.dubbo.config.spring.util.ObjectUtils.of;
+import static org.springframework.core.annotation.AnnotationAttributes.fromMap;
 import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
 
 /**
@@ -43,48 +47,30 @@ import static org.springframework.util.StringUtils.commaDelimitedListToStringArr
  *
  * @since 2.5.7
  */
-class ReferenceBeanBuilder extends AbstractAnnotationConfigBeanBuilder<Reference, ReferenceBean> {
+class ReferenceBeanBuilder extends AnnotatedInterfaceConfigBeanBuilder<ReferenceBean> {
 
     // Ignore those fields
     static final String[] IGNORE_FIELD_NAMES = of("application", "module", "consumer", "monitor", "registry");
 
-    private ReferenceBeanBuilder(Reference annotation, ClassLoader classLoader, ApplicationContext applicationContext) {
-        super(annotation, classLoader, applicationContext);
+    private ReferenceBeanBuilder(AnnotationAttributes attributes, ApplicationContext applicationContext) {
+        super(attributes, applicationContext);
     }
 
-    private void configureInterface(Reference reference, ReferenceBean referenceBean) {
+    private void configureInterface(AnnotationAttributes attributes, ReferenceBean referenceBean) {
 
-        Class<?> interfaceClass = reference.interfaceClass();
+        Class<?> serviceInterfaceClass = resolveServiceInterfaceClass(attributes, interfaceClass);
 
-        if (void.class.equals(interfaceClass)) {
-
-            interfaceClass = null;
-
-            String interfaceClassName = reference.interfaceName();
-
-            if (StringUtils.hasText(interfaceClassName)) {
-                if (ClassUtils.isPresent(interfaceClassName, classLoader)) {
-                    interfaceClass = ClassUtils.resolveClassName(interfaceClassName, classLoader);
-                }
-            }
-
-        }
-
-        if (interfaceClass == null) {
-            interfaceClass = this.interfaceClass;
-        }
-
-        Assert.isTrue(interfaceClass.isInterface(),
+        Assert.isTrue(serviceInterfaceClass.isInterface(),
                 "The class of field or method that was annotated @Reference is not an interface!");
 
-        referenceBean.setInterface(interfaceClass);
+        referenceBean.setInterface(serviceInterfaceClass);
 
     }
 
 
-    private void configureConsumerConfig(Reference reference, ReferenceBean<?> referenceBean) {
+    private void configureConsumerConfig(AnnotationAttributes attributes, ReferenceBean<?> referenceBean) {
 
-        String consumerBeanName = reference.consumer();
+        String consumerBeanName = getAttribute(attributes, "consumer");
 
         ConsumerConfig consumerConfig = getOptionalBean(applicationContext, consumerBeanName, ConsumerConfig.class);
 
@@ -92,10 +78,10 @@ class ReferenceBeanBuilder extends AbstractAnnotationConfigBeanBuilder<Reference
 
     }
 
-    void configureMethodConfig(Reference reference, ReferenceBean<?> referenceBean){
-        Method[] methods = reference.methods();
+    void configureMethodConfig(AnnotationAttributes attributes, ReferenceBean<?> referenceBean) {
+        Method[] methods = (Method[]) attributes.get("methods");
         List<MethodConfig> methodConfigs = MethodConfig.constructMethodConfig(methods);
-        if(!methodConfigs.isEmpty()){
+        if (!methodConfigs.isEmpty()) {
             referenceBean.setMethods(methodConfigs);
         }
     }
@@ -106,7 +92,7 @@ class ReferenceBeanBuilder extends AbstractAnnotationConfigBeanBuilder<Reference
     }
 
     @Override
-    protected void preConfigureBean(Reference reference, ReferenceBean referenceBean) {
+    protected void preConfigureBean(AnnotationAttributes attributes, ReferenceBean referenceBean) {
         Assert.notNull(interfaceClass, "The interface class must set first!");
         DataBinder dataBinder = new DataBinder(referenceBean);
         // Register CustomEditors for special fields
@@ -131,49 +117,53 @@ class ReferenceBeanBuilder extends AbstractAnnotationConfigBeanBuilder<Reference
         });
 
         // Bind annotation attributes
-        dataBinder.bind(new AnnotationPropertyValuesAdapter(reference, applicationContext.getEnvironment(), IGNORE_FIELD_NAMES));
+        dataBinder.bind(new AnnotationPropertyValuesAdapter(attributes, applicationContext.getEnvironment(), IGNORE_FIELD_NAMES));
 
     }
 
 
     @Override
-    protected String resolveModuleConfigBeanName(Reference annotation) {
-        return annotation.module();
+    protected String resolveModuleConfigBeanName(AnnotationAttributes attributes) {
+        return getAttribute(attributes, "module");
     }
 
     @Override
-    protected String resolveApplicationConfigBeanName(Reference annotation) {
-        return annotation.application();
+    protected String resolveApplicationConfigBeanName(AnnotationAttributes attributes) {
+        return getAttribute(attributes, "application");
     }
 
     @Override
-    protected String[] resolveRegistryConfigBeanNames(Reference annotation) {
-        return annotation.registry();
+    protected String[] resolveRegistryConfigBeanNames(AnnotationAttributes attributes) {
+        return getAttribute(attributes, "registry");
     }
 
     @Override
-    protected String resolveMonitorConfigBeanName(Reference annotation) {
-        return annotation.monitor();
+    protected String resolveMonitorConfigBeanName(AnnotationAttributes attributes) {
+        return getAttribute(attributes, "monitor");
     }
 
     @Override
-    protected void postConfigureBean(Reference annotation, ReferenceBean bean) throws Exception {
+    protected void postConfigureBean(AnnotationAttributes attributes, ReferenceBean bean) throws Exception {
 
         bean.setApplicationContext(applicationContext);
 
-        configureInterface(annotation, bean);
+        configureInterface(attributes, bean);
 
-        configureConsumerConfig(annotation, bean);
+        configureConsumerConfig(attributes, bean);
 
-        configureMethodConfig(annotation, bean);
+        configureMethodConfig(attributes, bean);
 
         bean.afterPropertiesSet();
 
     }
 
-    public static ReferenceBeanBuilder create(Reference annotation, ClassLoader classLoader,
+    @Deprecated
+    public static ReferenceBeanBuilder create(Reference reference, ClassLoader classLoader,
                                               ApplicationContext applicationContext) {
-        return new ReferenceBeanBuilder(annotation, classLoader, applicationContext);
+        return create(fromMap(getAttributes(reference, applicationContext.getEnvironment(), true)), applicationContext);
     }
 
+    public static ReferenceBeanBuilder create(AnnotationAttributes attributes, ApplicationContext applicationContext) {
+        return new ReferenceBeanBuilder(attributes, applicationContext);
+    }
 }
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
index 0edc5f3..06deb57 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
@@ -65,7 +65,7 @@ import static org.apache.dubbo.config.spring.util.AnnotationUtils.resolveService
 import static org.apache.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;
+import static org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation;
 import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes;
 import static org.springframework.util.ClassUtils.resolveClassName;
 
@@ -306,9 +306,9 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr
      * @since 2.7.3
      */
     private Annotation findServiceAnnotation(Class<?> beanClass) {
-        Annotation service = findAnnotation(beanClass, Service.class);
+        Annotation service = findMergedAnnotation(beanClass, Service.class);
         if (service == null) {
-            service = findAnnotation(beanClass, com.alibaba.dubbo.config.annotation.Service.class);
+            service = findMergedAnnotation(beanClass, com.alibaba.dubbo.config.annotation.Service.class);
         }
         return service;
     }
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilder.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilder.java
index 390e0b6..8aef87f 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilder.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilder.java
@@ -25,6 +25,7 @@ import org.springframework.core.annotation.AnnotationAttributes;
 import org.springframework.core.env.Environment;
 import org.springframework.util.StringUtils;
 
+import static org.apache.dubbo.config.spring.util.AnnotationUtils.getAttribute;
 import static org.apache.dubbo.config.spring.util.AnnotationUtils.resolveInterfaceName;
 import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes;
 
@@ -62,8 +63,8 @@ public class ServiceBeanNameBuilder {
 
     private ServiceBeanNameBuilder(AnnotationAttributes attributes, Class<?> defaultInterfaceClass, Environment environment) {
         this(resolveInterfaceName(attributes, defaultInterfaceClass), environment);
-        this.group(attributes.getString("group"));
-        this.version(attributes.getString("version"));
+        this.group(getAttribute(attributes,"group"));
+        this.version(getAttribute(attributes,"version"));
     }
 
     /**
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtils.java
index bf065f8..c46ca8a 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtils.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtils.java
@@ -18,18 +18,27 @@ package org.apache.dubbo.config.spring.util;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
 import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.support.BeanDefinitionRegistry;
 import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
+import org.springframework.core.type.AnnotationMetadata;
 import org.springframework.util.ObjectUtils;
 
 import java.lang.annotation.Annotation;
-import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Objects;
+
+import static java.lang.String.format;
+import static java.util.Arrays.asList;
+import static org.springframework.util.ClassUtils.resolveClassName;
 
 /**
  * Annotated {@link BeanDefinition} Utilities
  * <p>
  * The source code is cloned from https://github.com/alibaba/spring-context-support/blob/1.0.2/src/main/java/com/alibaba/spring/util/AnnotatedBeanDefinitionRegistryUtils.java
+ *
  * @since 2.6.6
  */
 public abstract class AnnotatedBeanDefinitionRegistryUtils {
@@ -37,10 +46,47 @@ public abstract class AnnotatedBeanDefinitionRegistryUtils {
     private static final Log logger = LogFactory.getLog(AnnotatedBeanDefinitionRegistryUtils.class);
 
     /**
-     * Register Beans
+     * Is present bean that was registered by the specified {@link Annotation annotated} {@link Class class}
+     *
+     * @param registry       {@link BeanDefinitionRegistry}
+     * @param annotatedClass the {@link Annotation annotated} {@link Class class}
+     * @return if present, return <code>true</code>, or <code>false</code>
+     * @since 2.7.3
+     */
+    public static boolean isPresentBean(BeanDefinitionRegistry registry, Class<?> annotatedClass) {
+
+        boolean present = false;
+
+        String[] beanNames = registry.getBeanDefinitionNames();
+
+        ClassLoader classLoader = annotatedClass.getClassLoader();
+
+        for (String beanName : beanNames) {
+            BeanDefinition beanDefinition = registry.getBeanDefinition(beanName);
+            if (beanDefinition instanceof AnnotatedBeanDefinition) {
+                AnnotationMetadata annotationMetadata = ((AnnotatedBeanDefinition) beanDefinition).getMetadata();
+                String className = annotationMetadata.getClassName();
+                Class<?> targetClass = resolveClassName(className, classLoader);
+                present = Objects.equals(targetClass, annotatedClass);
+                if (present) {
+                    if (logger.isDebugEnabled()) {
+                        logger.debug(format("The annotatedClass[class : %s , bean name : %s] was present in registry[%s]",
+                                className, beanName, registry));
+                    }
+                    break;
+                }
+            }
+        }
+
+        return present;
+    }
+
+    /**
+     * Register Beans if not present in {@link BeanDefinitionRegistry registry}
      *
      * @param registry         {@link BeanDefinitionRegistry}
      * @param annotatedClasses {@link Annotation annotation} class
+     * @revision 2.7.3 {@link #isPresentBean(BeanDefinitionRegistry, Class)}
      */
     public static void registerBeans(BeanDefinitionRegistry registry, Class<?>... annotatedClasses) {
 
@@ -50,10 +96,20 @@ public abstract class AnnotatedBeanDefinitionRegistryUtils {
 
         boolean debugEnabled = logger.isDebugEnabled();
 
+        // Remove all annotated-classes that have been registered
+        Iterator<Class<?>> iterator = new ArrayList<>(asList(annotatedClasses)).iterator();
+
+        while (iterator.hasNext()) {
+            Class<?> annotatedClass = iterator.next();
+            if (isPresentBean(registry, annotatedClass)) {
+                iterator.remove();
+            }
+        }
+
         AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(registry);
 
         if (debugEnabled) {
-            logger.debug(registry.getClass().getSimpleName() + " will register annotated classes : " + Arrays.asList(annotatedClasses) + " .");
+            logger.debug(registry.getClass().getSimpleName() + " will register annotated classes : " + asList(annotatedClasses) + " .");
         }
 
         reader.register(annotatedClasses);
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotationUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotationUtils.java
index 600c1b7..3b308d3 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotationUtils.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotationUtils.java
@@ -30,22 +30,26 @@ import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
+import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Method;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import static java.lang.String.valueOf;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.unmodifiableMap;
+import static org.springframework.core.annotation.AnnotatedElementUtils.getMergedAnnotation;
+import static org.springframework.core.annotation.AnnotationAttributes.fromMap;
 import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
 import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes;
 import static org.springframework.core.annotation.AnnotationUtils.getDefaultValue;
 import static org.springframework.util.ClassUtils.getAllInterfacesForClass;
 import static org.springframework.util.ClassUtils.resolveClassName;
-import static org.springframework.util.CollectionUtils.arrayToList;
+import static org.springframework.util.CollectionUtils.isEmpty;
+import static org.springframework.util.ObjectUtils.containsElement;
 import static org.springframework.util.ObjectUtils.nullSafeEquals;
 import static org.springframework.util.StringUtils.hasText;
 import static org.springframework.util.StringUtils.trimWhitespace;
@@ -89,46 +93,43 @@ public class AnnotationUtils {
      * @throws IllegalStateException if interface name was not found
      */
     public static String resolveInterfaceName(AnnotationAttributes attributes, Class<?> defaultInterfaceClass) {
+        return resolveServiceInterfaceClass(attributes, defaultInterfaceClass).getName();
+    }
 
-        String interfaceName = null;
-
-        Class<?> interfaceClass = attributes.getClass("interfaceClass");
-        if (interfaceClass != null && !void.class.equals(interfaceClass)) {
-            interfaceName = interfaceClass.getName();
-        } else if ((!hasText(interfaceName = attributes.getString("interfaceName")))) {
-            interfaceName = defaultInterfaceClass.isInterface() ? defaultInterfaceClass.getName() : null;
-        }
-
-        if (!hasText(interfaceName)) {
-            throw new IllegalStateException(
-                    "The @Service undefined interfaceClass or interfaceName, and the type "
-                            + defaultInterfaceClass.getName() + " is not a interface.");
-        }
-
-        return interfaceName;
+    /**
+     * Get the attribute value
+     *
+     * @param attributes {@link AnnotationAttributes the annotation attributes}
+     * @param name       the name of attribute
+     * @param <T>        the type of attribute value
+     * @return the attribute value if found
+     * @since 2.7.3
+     */
+    public static <T> T getAttribute(AnnotationAttributes attributes, String name) {
+        return (T) attributes.get(name);
     }
 
     /**
      * Resolve the {@link Class class} of Dubbo Service interface from the specified
      * {@link AnnotationAttributes annotation attributes} and annotated {@link Class class}.
      *
-     * @param attributes     {@link AnnotationAttributes annotation attributes}
-     * @param annotatedClass the annotated {@link Class class}.
+     * @param attributes            {@link AnnotationAttributes annotation attributes}
+     * @param defaultInterfaceClass the annotated {@link Class class}.
      * @return the {@link Class class} of Dubbo Service interface
      * @throws IllegalArgumentException if can't resolved
      */
-    public static Class<?> resolveServiceInterfaceClass(AnnotationAttributes attributes, Class<?> annotatedClass)
+    public static Class<?> resolveServiceInterfaceClass(AnnotationAttributes attributes, Class<?> defaultInterfaceClass)
             throws IllegalArgumentException {
 
-        ClassLoader classLoader = annotatedClass.getClassLoader();
+        ClassLoader classLoader = defaultInterfaceClass != null ? defaultInterfaceClass.getClassLoader() : Thread.currentThread().getContextClassLoader();
 
-        Class<?> interfaceClass = attributes.getClass("interfaceClass");
+        Class<?> interfaceClass = getAttribute(attributes, "interfaceClass");
 
         if (void.class.equals(interfaceClass)) { // default or set void.class for purpose.
 
             interfaceClass = null;
 
-            String interfaceClassName = attributes.getString("interfaceName");
+            String interfaceClassName = getAttribute(attributes, "interfaceName");
 
             if (hasText(interfaceClassName)) {
                 if (ClassUtils.isPresent(interfaceClassName, classLoader)) {
@@ -138,10 +139,10 @@ public class AnnotationUtils {
 
         }
 
-        if (interfaceClass == null) {
+        if (interfaceClass == null && defaultInterfaceClass != null) {
             // Find all interfaces from the annotated class
             // To resolve an issue : https://github.com/apache/dubbo/issues/3251
-            Class<?>[] allInterfaces = getAllInterfacesForClass(annotatedClass);
+            Class<?>[] allInterfaces = getAllInterfacesForClass(defaultInterfaceClass);
 
             if (allInterfaces.length > 0) {
                 interfaceClass = allInterfaces[0];
@@ -153,7 +154,7 @@ public class AnnotationUtils {
                 "@Service interfaceClass() or interfaceName() or interface class must be present!");
 
         Assert.isTrue(interfaceClass.isInterface(),
-                "The type that was annotated @Service is not an interface!");
+                "The annotated type must be an interface!");
 
         return interfaceClass;
     }
@@ -292,7 +293,7 @@ public class AnnotationUtils {
 
         }
 
-        return Collections.unmodifiableMap(annotationsMap);
+        return unmodifiableMap(annotationsMap);
 
     }
 
@@ -304,7 +305,9 @@ public class AnnotationUtils {
      * @param ignoreAttributeNames the attribute names of annotation should be ignored
      * @return non-null
      * @since 2.6.6
+     * @deprecated
      */
+    @Deprecated
     public static Map<String, Object> getAttributes(Annotation annotation, boolean ignoreDefaultValue,
                                                     String... ignoreAttributeNames) {
         return getAttributes(annotation, null, ignoreDefaultValue, ignoreAttributeNames);
@@ -323,11 +326,13 @@ public class AnnotationUtils {
     public static Map<String, Object> getAttributes(Annotation annotation, PropertyResolver propertyResolver,
                                                     boolean ignoreDefaultValue, String... ignoreAttributeNames) {
 
-        Set<String> ignoreAttributeNamesSet = new HashSet<String>(arrayToList(ignoreAttributeNames));
+        if (annotation == null) {
+            return emptyMap();
+        }
 
         Map<String, Object> attributes = getAnnotationAttributes(annotation);
 
-        Map<String, Object> actualAttributes = new LinkedHashMap<String, Object>();
+        Map<String, Object> actualAttributes = new LinkedHashMap<>();
 
         for (Map.Entry<String, Object> entry : attributes.entrySet()) {
 
@@ -339,11 +344,6 @@ public class AnnotationUtils {
                 continue;
             }
 
-            // ignore attribute name
-            if (ignoreAttributeNamesSet.contains(attributeName)) {
-                continue;
-            }
-
             /**
              * @since 2.7.1
              * ignore annotation member
@@ -354,6 +354,42 @@ public class AnnotationUtils {
             if (attributeValue.getClass().isArray() && attributeValue.getClass().getComponentType().isAnnotation()) {
                 continue;
             }
+            actualAttributes.put(attributeName, attributeValue);
+        }
+
+
+        return resolvePlaceholders(actualAttributes, propertyResolver, ignoreAttributeNames);
+    }
+
+    /**
+     * Resolve the placeholders from the specified annotation attributes
+     *
+     * @param sourceAnnotationAttributes the source of annotation attributes
+     * @param propertyResolver           {@link PropertyResolver}
+     * @param ignoreAttributeNames       the attribute names to be ignored
+     * @return a new resolved annotation attributes , non-null and read-only
+     * @since 2.7.3
+     */
+    public static Map<String, Object> resolvePlaceholders(Map<String, Object> sourceAnnotationAttributes,
+                                                          PropertyResolver propertyResolver,
+                                                          String... ignoreAttributeNames) {
+
+        if (isEmpty(sourceAnnotationAttributes)) {
+            return emptyMap();
+        }
+
+        Map<String, Object> resolvedAnnotationAttributes = new LinkedHashMap<>();
+
+        for (Map.Entry<String, Object> entry : sourceAnnotationAttributes.entrySet()) {
+
+            String attributeName = entry.getKey();
+
+            // ignore attribute name to skip
+            if (containsElement(ignoreAttributeNames, attributeName)) {
+                continue;
+            }
+
+            Object attributeValue = entry.getValue();
 
             if (attributeValue instanceof String) {
                 attributeValue = resolvePlaceholders(valueOf(attributeValue), propertyResolver);
@@ -364,9 +400,32 @@ public class AnnotationUtils {
                 }
                 attributeValue = values;
             }
-            actualAttributes.put(attributeName, attributeValue);
+
+            resolvedAnnotationAttributes.put(attributeName, attributeValue);
         }
-        return actualAttributes;
+
+        return unmodifiableMap(resolvedAnnotationAttributes);
+    }
+
+    /**
+     * Get {@link AnnotationAttributes the annotation attributes} after merging and resolving the placeholders
+     *
+     * @param annotatedElement     {@link AnnotatedElement the annotated element}
+     * @param annotationType       the {@link Class tyoe} pf {@link Annotation annotation}
+     * @param propertyResolver     {@link PropertyResolver} instance, e.g {@link Environment}
+     * @param ignoreDefaultValue   whether ignore default value or not
+     * @param ignoreAttributeNames the attribute names of annotation should be ignored
+     * @return non-null
+     * @since 2.7.3
+     */
+    public static AnnotationAttributes getMergedAttributes(AnnotatedElement annotatedElement,
+                                                           Class<? extends Annotation> annotationType,
+                                                           PropertyResolver propertyResolver,
+                                                           boolean ignoreDefaultValue,
+                                                           String... ignoreAttributeNames) {
+        Annotation annotation = getMergedAnnotation(annotatedElement, annotationType);
+        return fromMap(getAttributes(annotation, propertyResolver, ignoreDefaultValue, ignoreAttributeNames));
+
     }
 
     private static String resolvePlaceholders(String attributeValue, PropertyResolver propertyResolver) {
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/BeanFactoryUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/BeanFactoryUtils.java
index 71fb767..558986e 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/BeanFactoryUtils.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/BeanFactoryUtils.java
@@ -29,9 +29,11 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
+import static java.util.Collections.emptyList;
 import static org.springframework.beans.factory.BeanFactoryUtils.beanNamesForTypeIncludingAncestors;
 import static org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors;
 import static org.springframework.util.ObjectUtils.containsElement;
+import static org.springframework.util.ObjectUtils.isEmpty;
 
 /**
  * {@link BeanFactory} Utilities class
@@ -104,6 +106,10 @@ public class BeanFactoryUtils {
      */
     public static <T> List<T> getBeans(ListableBeanFactory beanFactory, String[] beanNames, Class<T> beanType) {
 
+        if (isEmpty(beanNames)) {
+            return emptyList();
+        }
+
         String[] allBeanNames = beanNamesForTypeIncludingAncestors(beanFactory, beanType);
 
         List<T> beans = new ArrayList<T>(beanNames.length);
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/context/annotation/provider/DefaultHelloService.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/annotation/merged/MergedReference.java
similarity index 52%
copy from dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/context/annotation/provider/DefaultHelloService.java
copy to dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/annotation/merged/MergedReference.java
index b484d26..9d34077 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/context/annotation/provider/DefaultHelloService.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/annotation/merged/MergedReference.java
@@ -14,25 +14,28 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.config.spring.context.context.annotation.provider;
+package org.apache.dubbo.config.spring.annotation.merged;
 
-import org.apache.dubbo.config.spring.api.HelloService;
 
-import org.springframework.stereotype.Service;
+import org.apache.dubbo.config.annotation.Reference;
 
-/**
- * Default {@link HelloService} annotation with Spring's {@link Service}
- * and Dubbo's {@link org.apache.dubbo.config.annotation.Service}
- *
- * @since TODO
- */
-@Service
-@org.apache.dubbo.config.annotation.Service
-public class DefaultHelloService implements HelloService {
+import org.springframework.core.annotation.AliasFor;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
+@Reference
+public @interface MergedReference {
 
-    @Override
-    public String sayHello(String name) {
-        return "Greeting, " + name;
-    }
+    @AliasFor(annotation = Reference.class, attribute = "group")
+    String group() default "dubbo";
 
+    @AliasFor(annotation = Reference.class, attribute = "version")
+    String version() default "1.0.0";
 }
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/context/annotation/provider/DefaultHelloService.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/annotation/merged/MergedService.java
similarity index 54%
copy from dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/context/annotation/provider/DefaultHelloService.java
copy to dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/annotation/merged/MergedService.java
index b484d26..cfe1243 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/context/annotation/provider/DefaultHelloService.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/annotation/merged/MergedService.java
@@ -14,25 +14,28 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.config.spring.context.context.annotation.provider;
+package org.apache.dubbo.config.spring.annotation.merged;
 
-import org.apache.dubbo.config.spring.api.HelloService;
 
-import org.springframework.stereotype.Service;
+import org.apache.dubbo.config.annotation.Service;
 
-/**
- * Default {@link HelloService} annotation with Spring's {@link Service}
- * and Dubbo's {@link org.apache.dubbo.config.annotation.Service}
- *
- * @since TODO
- */
+import org.springframework.core.annotation.AliasFor;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
 @Service
-@org.apache.dubbo.config.annotation.Service
-public class DefaultHelloService implements HelloService {
+public @interface MergedService {
 
-    @Override
-    public String sayHello(String name) {
-        return "Greeting, " + name;
-    }
+    @AliasFor(annotation = Service.class, attribute = "group")
+    String group() default "dubbo";
 
+    @AliasFor(annotation = Service.class, attribute = "version")
+    String version() default "1.0.0";
 }
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/MergedAnnotationTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/MergedAnnotationTest.java
new file mode 100644
index 0000000..48c04eb
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/MergedAnnotationTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.config.spring.beans.factory.annotation;
+
+import org.apache.dubbo.config.annotation.Reference;
+import org.apache.dubbo.config.annotation.Service;
+import org.apache.dubbo.config.spring.annotation.merged.MergedReference;
+import org.apache.dubbo.config.spring.annotation.merged.MergedService;
+import org.apache.dubbo.config.spring.api.DemoService;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.util.ReflectionUtils;
+
+import java.lang.reflect.Field;
+
+public class MergedAnnotationTest {
+
+    @Test
+    public void testMergedReference() {
+        Field field = ReflectionUtils.findField(MergedAnnotationTest.TestBean1.class, "demoService");
+        Reference reference = AnnotatedElementUtils.getMergedAnnotation(field, Reference.class);
+        Assert.assertEquals("dubbo", reference.group());
+        Assert.assertEquals("1.0.0", reference.version());
+
+        Field field2 = ReflectionUtils.findField(MergedAnnotationTest.TestBean2.class, "demoService");
+        Reference reference2 = AnnotatedElementUtils.getMergedAnnotation(field2, Reference.class);
+        Assert.assertEquals("group", reference2.group());
+        Assert.assertEquals("2.0", reference2.version());
+    }
+
+    @Test
+    public void testMergedService() {
+        Service service1 = AnnotatedElementUtils.getMergedAnnotation(MergedAnnotationTest.DemoServiceImpl1.class, Service.class);
+        Assert.assertEquals("dubbo", service1.group());
+        Assert.assertEquals("1.0.0", service1.version());
+
+        Service service2 = AnnotatedElementUtils.getMergedAnnotation(MergedAnnotationTest.DemoServiceImpl2.class, Service.class);
+        Assert.assertEquals("group", service2.group());
+        Assert.assertEquals("2.0", service2.version());
+    }
+
+    @MergedService
+    public static class DemoServiceImpl1 {
+    }
+
+    @MergedService(group = "group", version = "2.0")
+    public static class DemoServiceImpl2 {
+    }
+
+    private static class TestBean1 {
+        @MergedReference
+        private DemoService demoService;
+    }
+
+    private static class TestBean2 {
+        @MergedReference(group = "group", version = "2.0")
+        private DemoService demoService;
+    }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
index 6f62678..1ee01dc 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
@@ -229,7 +229,7 @@ public class ReferenceAnnotationBeanPostProcessorTest {
             return demoService;
         }
 
-        @Reference(version = "2.5.7", url = "dubbo://127.0.0.1:12345")
+        @com.alibaba.dubbo.config.annotation.Reference(version = "2.5.7", url = "dubbo://127.0.0.1:12345")
         public void setDemoService(DemoService demoService) {
             this.demoService = demoService;
         }
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/context/annotation/provider/DefaultHelloService.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/context/annotation/provider/DefaultHelloService.java
index b484d26..8277bc9 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/context/annotation/provider/DefaultHelloService.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/context/annotation/provider/DefaultHelloService.java
@@ -16,6 +16,7 @@
  */
 package org.apache.dubbo.config.spring.context.context.annotation.provider;
 
+import org.apache.dubbo.config.spring.annotation.merged.MergedService;
 import org.apache.dubbo.config.spring.api.HelloService;
 
 import org.springframework.stereotype.Service;
@@ -27,7 +28,8 @@ import org.springframework.stereotype.Service;
  * @since TODO
  */
 @Service
-@org.apache.dubbo.config.annotation.Service
+//@org.apache.dubbo.config.annotation.Service
+@MergedService
 public class DefaultHelloService implements HelloService {
 
     @Override
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtilsTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtilsTest.java
new file mode 100644
index 0000000..05c4a78
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtilsTest.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.config.spring.util;
+
+import org.junit.Assert;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.stereotype.Service;
+
+import static org.apache.dubbo.config.spring.util.AnnotatedBeanDefinitionRegistryUtils.isPresentBean;
+import static org.apache.dubbo.config.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * {@link AnnotatedBeanDefinitionRegistryUtils} Test
+ *
+ * @since 2.7.3
+ */
+public class AnnotatedBeanDefinitionRegistryUtilsTest {
+
+    private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
+
+    @AfterEach
+    public void destroy() {
+        context.close();
+    }
+
+    @Test
+    public void testIsPresentBean() {
+
+        assertFalse(isPresentBean(context, A.class));
+
+        context.register(A.class);
+
+        for (int i = 0; i < 9; i++) {
+            assertTrue(isPresentBean(context, A.class));
+        }
+
+    }
+
+    @Test
+    public void testRegisterBeans() {
+
+        registerBeans(context, A.class, A.class);
+
+        context.refresh();
+
+        A a = context.getBean(A.class);
+
+        Assert.assertNotNull(a);
+    }
+
+
+    @Service
+    static class A {
+
+    }
+}