You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by mi...@apache.org on 2019/02/25 09:26:33 UTC

[incubator-dubbo] branch 2.6.x updated: [Enhancement] inline the source code of spring-context-support (#3225)

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

min pushed a commit to branch 2.6.x
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo.git


The following commit(s) were added to refs/heads/2.6.x by this push:
     new fec3363  [Enhancement] inline the source code of spring-context-support (#3225)
fec3363 is described below

commit fec3363b749140dd7c96a4009f826f84c2941a82
Author: Mercy Ma <me...@gmail.com>
AuthorDate: Mon Feb 25 17:26:06 2019 +0800

    [Enhancement] inline the source code of spring-context-support (#3225)
    
    * Manually merge pull request #1486, to make travis ci and codecov work after apache incubator transition.
    
    * Polish alibaba/dubbo#1306
    
    * Optimize imports
    
    * Optimize imports
    
    * Remove invalid JavaDoc
    
    * Update DubboConfigBinder.java
    
    Remove invalid JavaDoc
    
    * Fix apache/incubator-dubbo#1653
    
    * Fixed apache/incubator-dubbo#1772
    
    * Reactor ReferenceAnnotationBeanPostProcessor
    
    * Fixed incubator-dubbo-spring-boot-project#243
    
    * Add ServiceBeanNameBuilder
    
    * Polish apache/incubator-dubbo/#2235
    
    * Polish incubator-dubbo#2251
    
    * Update spring-context-supprt version to be release
    
    * Rename ServiceBeanExportEvent to be ServiceBeanExportedEvent
    
    * Poblish apache/incubator-dubbo#2297
    
    * Polish apache/incubator-dubbo#2301
    
    * Polish apache/incubator-dubbo#2315
    
    * Polish apache/incubator-dubbo#2897 : DubboConfigConfigurationSelector precedence is too high
    
    * Polish apache/incubator-dubbo#2897 : implements ImportBeanDefinitionRegistrar in order to reduce precedence
    
    * Polish apache/incubator-dubbo#2897 : rename DubboConfigConfigurationSelector to DubboConfigConfigurationRegistrar
    
    * Polish apache/incubator-dubbo#3192 : inline the source code of spring-context-support
    
    * Fixed the issues of the test-cases
    
    * Polish apache/incubator-dubbo#3193 : [Enhancement] Change the default behavior of @EnableDubboConfig.multiple()
    
    * Polish apache/incubator-dubbo#3192 : inline the source code of spring-context-support
    
    * Polish apache/incubator-dubbo#3189 Simplify externalized configuration of Dubbo Protocol name
    
    * Polish apache/incubator-dubbo#3193
    
    * Polish apache/incubator-dubbo#2987
    
    * Polish apache/incubator-dubbo#3355 : Add the "protocol" attribute
    
    * Polish apache/incubator-dubbo#3355 : Still exists the issues in service discovery.
    
    * Polish apache/incubator-dubbo#3355 : fix the issues in samples
    
    * Polish apache/incubator-dubbo#3355 : fix the issues in samples
    
    * Polish apache/incubator-dubbo#3296 : Merge and enhancement dubbo-registry-nacos
    
    * Polish apache/incubator-dubbo#3251 : @Service supports the hierarchical interface
    
    * Polish apache/incubator-dubbo#3275 : ReferenceBeanInvocationHandler does not throw the actual exception
    
    * Polish apache/incubator-dubbo#3429 : Fix the NPE
    
    * add license header
    
    * Polish apache/incubator-dubbo#3296 : Supports Docker
---
 dependencies-bom/pom.xml                           |  12 +-
 .../alibaba/dubbo/config/annotation/Reference.java | 238 ++++-----
 dubbo-config/dubbo-config-spring/pom.xml           |  93 +++-
 .../AbstractAnnotationConfigBeanBuilder.java       |   4 +-
 .../annotation/AnnotationBeanNameBuilder.java      | 142 ++++++
 .../AnnotationInjectedBeanPostProcessor.java       | 529 +++++++++++++++++++++
 .../AnnotationPropertyValuesAdapter.java           |   2 +-
 .../DubboConfigBindingBeanPostProcessor.java       |  56 ++-
 .../ReferenceAnnotationBeanPostProcessor.java      |  23 +-
 .../factory/annotation/ReferenceBeanBuilder.java   |   4 +-
 .../ServiceAnnotationBeanPostProcessor.java        |  13 +-
 .../factory/annotation/ServiceBeanNameBuilder.java |   2 +
 .../annotation/DubboConfigBindingRegistrar.java    |  14 +-
 ...java => DubboConfigConfigurationRegistrar.java} |  35 +-
 .../spring/context/annotation/EnableDubbo.java     |   2 +-
 .../context/annotation/EnableDubboConfig.java      |  13 +-
 .../context/config/DubboConfigBeanCustomizer.java  |  46 ++
 ...pertyDefaultValueDubboConfigBeanCustomizer.java |  75 +++
 .../properties/DefaultDubboConfigBinder.java       |   2 +-
 .../spring/extension/SpringExtensionFactory.java   | 222 ++++-----
 .../spring/status/DataSourceStatusChecker.java     | 192 ++++----
 .../config/spring/status/SpringStatusChecker.java  | 184 +++----
 .../util/AnnotatedBeanDefinitionRegistryUtils.java |  62 +++
 .../dubbo/config/spring/util/AnnotationUtils.java  | 214 ++++++++-
 .../dubbo/config/spring/util/BeanFactoryUtils.java |  63 ++-
 .../dubbo/config/spring/util/BeanRegistrar.java    |   2 +-
 .../dubbo/config/spring/util/ClassUtils.java}      |  21 +-
 .../dubbo/config/spring/util/ObjectUtils.java}     |  21 +-
 .../config/spring/util/PropertySourcesUtils.java   | 112 +++++
 .../dubbo/config/spring/api/HelloService.java      |   9 +-
 ...est.java => AnnotationBeanNameBuilderTest.java} |  47 +-
 .../DubboConfigBindingBeanPostProcessorTest.java   |  50 +-
 .../ReferenceAnnotationBeanPostProcessorTest.java  |   6 +-
 .../annotation/ReferenceBeanBuilderTest.java       | 124 +++++
 .../annotation/ServiceBeanNameBuilderTest.java     |   1 +
 .../annotation/multiple/EmbeddedZooKeeper.java     | 252 ++++++++++
 .../consumer/MultipleProtocolsServiceConsumer.java |  77 +++
 .../multiple/provider/DefaultHelloService.java}    |  14 +-
 .../MultipleProtocolsServiceProvider.java}         |  48 +-
 .../DubboComponentScanRegistrarTest.java           |  26 +
 .../DubboConfigBindingRegistrarTest.java           |  14 +-
 .../DubboConfigBindingsRegistrarTest.java          |   2 +-
 .../annotation/DubboConfigConfigurationTest.java   |   4 +-
 .../context/annotation/EnableDubboConfigTest.java  |  31 +-
 .../spring/context/annotation/EnableDubboTest.java |  38 +-
 .../annotation/provider/DemoServiceImpl.java       |   9 +-
 .../AnnotatedBeanDefinitionRegistryUtilsTest.java  |  59 +++
 .../spring/util/PropertySourcesUtilsTest.java      |  80 ++++
 .../src/test/resources/META-INF/config.properties  |   6 +-
 .../resources/META-INF/dubbo-common.properties     |   2 +
 .../multiple-protocols-consumer.properties         |   1 +
 .../multiple-protocols-provider.properties         |   6 +
 .../META-INF/spring/dubbo-rest-consumer.xml        |  32 ++
 .../dubbo/registry/support/DubboRegistration.java  |  93 ++++
 .../dubbo/registry/support/Registration.java       |  37 +-
 .../registry/support/ServiceInstanceRegistry.java  | 474 ++++++++++++++++++
 dubbo-registry/dubbo-registry-nacos/pom.xml        | 160 +++++++
 .../dubbo/registry/nacos/NacosRegistry.java        | 198 ++++++++
 .../dubbo/registry/nacos/NacosRegistryFactory.java | 108 +++++
 .../com.alibaba.dubbo.registry.RegistryFactory     |   1 +
 .../consumer/DemoServiceConsumerBootstrap.java     |  59 +++
 .../consumer/DemoServiceConsumerXmlBootstrap.java  |  42 ++
 .../provider/DemoServiceProviderBootstrap.java     |  45 +-
 .../provider/DemoServiceProviderXmlBootstrap.java  |  21 +-
 .../alibaba/dubbo/demo/service/DefaultService.java |  46 ++
 .../alibaba/dubbo/demo/service/DemoService.java    |  20 +-
 .../registry/nacos/NacosRegistryFactoryTest.java   |  11 +-
 .../dubbo/registry/nacos/NacosRegistryTest.java    |  16 +-
 .../META-INF/spring/dubbo-consumer-context.xml     |  16 +
 .../META-INF/spring/dubbo-provider-context.xml     |  21 +
 .../src/test/resources/consumer-config.properties  |   6 +
 .../src/test/resources/provider-config.properties  |  14 +
 dubbo-registry/pom.xml                             |   1 +
 .../dubbo/rpc/protocol/rest/RestProtocol.java      |  10 +-
 74 files changed, 4081 insertions(+), 654 deletions(-)

diff --git a/dependencies-bom/pom.xml b/dependencies-bom/pom.xml
index 205abac..cf8f2ec 100644
--- a/dependencies-bom/pom.xml
+++ b/dependencies-bom/pom.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
@@ -101,6 +102,7 @@
         <rs_api_version>2.0</rs_api_version>
         <resteasy_version>3.0.19.Final</resteasy_version>
         <tomcat_embed_version>8.5.31</tomcat_embed_version>
+
         <!-- Log libs -->
         <slf4j_version>1.7.25</slf4j_version>
         <jcl_version>1.2</jcl_version>
@@ -302,6 +304,7 @@
                 <artifactId>tomcat-embed-logging-juli</artifactId>
                 <version>${tomcat_embed_version}</version>
             </dependency>
+
             <!-- Log libs -->
             <dependency>
                 <groupId>org.slf4j</groupId>
@@ -363,13 +366,6 @@
 
             <!-- Alibaba extensions -->
 
-            <!-- Spring Context Support -->
-            <dependency>
-                <groupId>com.alibaba.spring</groupId>
-                <artifactId>spring-context-support</artifactId>
-                <version>${alibaba_spring_context_support_version}</version>
-            </dependency>
-
             <!-- YAML -->
             <dependency>
                 <groupId>org.yaml</groupId>
diff --git a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Reference.java b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Reference.java
index c043cb3..b3a93d7 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Reference.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Reference.java
@@ -1,115 +1,123 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.alibaba.dubbo.config.annotation;
-
-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;
-
-/**
- * Reference
- *
- * @export
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
-public @interface Reference {
-
-    Class<?> interfaceClass() default void.class;
-
-    String interfaceName() default "";
-
-    String version() default "";
-
-    String group() default "";
-
-    String url() default "";
-
-    String client() default "";
-
-    boolean generic() default false;
-
-    boolean injvm() default false;
-
-    boolean check() default true;
-
-    boolean init() default false;
-
-    boolean lazy() default false;
-
-    boolean stubevent() default false;
-
-    String reconnect() default "";
-
-    boolean sticky() default false;
-
-    String proxy() default "";
-
-    String stub() default "";
-
-    String cluster() default "";
-
-    int connections() default 0;
-
-    int callbacks() default 0;
-
-    String onconnect() default "";
-
-    String ondisconnect() default "";
-
-    String owner() default "";
-
-    String layer() default "";
-
-    int retries() default 2;
-
-    String loadbalance() default "";
-
-    boolean async() default false;
-
-    int actives() default 0;
-
-    boolean sent() default false;
-
-    String mock() default "";
-
-    String validation() default "";
-
-    int timeout() default 0;
-
-    String cache() default "";
-
-    String[] filter() default {};
-
-    String[] listener() default {};
-
-    String[] parameters() default {};
-
-    String application() default "";
-
-    String module() default "";
-
-    String consumer() default "";
-
-    String monitor() default "";
-
-    String[] registry() default {};
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.config.annotation;
+
+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;
+
+/**
+ * Reference
+ *
+ * @export
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
+public @interface Reference {
+
+    Class<?> interfaceClass() default void.class;
+
+    String interfaceName() default "";
+
+    String version() default "";
+
+    String group() default "";
+
+    String url() default "";
+
+    String client() default "";
+
+    boolean generic() default false;
+
+    boolean injvm() default false;
+
+    boolean check() default true;
+
+    boolean init() default false;
+
+    boolean lazy() default false;
+
+    boolean stubevent() default false;
+
+    String reconnect() default "";
+
+    boolean sticky() default false;
+
+    String proxy() default "";
+
+    String stub() default "";
+
+    String cluster() default "";
+
+    int connections() default 0;
+
+    int callbacks() default 0;
+
+    String onconnect() default "";
+
+    String ondisconnect() default "";
+
+    String owner() default "";
+
+    String layer() default "";
+
+    int retries() default 2;
+
+    String loadbalance() default "";
+
+    boolean async() default false;
+
+    int actives() default 0;
+
+    boolean sent() default false;
+
+    String mock() default "";
+
+    String validation() default "";
+
+    int timeout() default 0;
+
+    String cache() default "";
+
+    String[] filter() default {};
+
+    String[] listener() default {};
+
+    String[] parameters() default {};
+
+    String application() default "";
+
+    String module() default "";
+
+    String consumer() default "";
+
+    String monitor() default "";
+
+    String[] registry() default {};
+
+    /**
+     * The communication protocol of Dubbo Service
+     *
+     * @return the default value is ""
+     * @since 2.6.6
+     */
+    String protocol() default "";
+
+}
diff --git a/dubbo-config/dubbo-config-spring/pom.xml b/dubbo-config/dubbo-config-spring/pom.xml
index f2c29c3..e6f895f 100644
--- a/dubbo-config/dubbo-config-spring/pom.xml
+++ b/dubbo-config/dubbo-config-spring/pom.xml
@@ -14,7 +14,8 @@
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>com.alibaba</groupId>
@@ -47,91 +48,173 @@
             <artifactId>spring-context</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.alibaba.spring</groupId>
-            <artifactId>spring-context-support</artifactId>
-        </dependency>
-        <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
             <scope>provided</scope>
         </dependency>
+
+        <!-- Test -->
+        <!-- Netty -->
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-all</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <!-- REST support dependencies -->
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-jaxrs</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-client</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-netty4</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-jackson-provider</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-jaxb-provider</artifactId>
+            <scope>test</scope>
+        </dependency>
+
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>dubbo-registry-default</artifactId>
             <version>${project.parent.version}</version>
             <scope>test</scope>
         </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>dubbo-registry-zookeeper</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>dubbo-monitor-default</artifactId>
             <version>${project.parent.version}</version>
             <scope>test</scope>
         </dependency>
+
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>dubbo-rpc-dubbo</artifactId>
             <version>${project.parent.version}</version>
             <scope>test</scope>
         </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>dubbo-rpc-rest</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>dubbo-rpc-rmi</artifactId>
             <version>${project.parent.version}</version>
             <scope>test</scope>
         </dependency>
+
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>dubbo-rpc-injvm</artifactId>
             <version>${project.parent.version}</version>
         </dependency>
+
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>dubbo-remoting-netty4</artifactId>
             <version>${project.parent.version}</version>
             <scope>test</scope>
         </dependency>
+
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>dubbo-serialization-hessian2</artifactId>
             <version>${project.parent.version}</version>
             <scope>test</scope>
         </dependency>
+
         <dependency>
             <groupId>javax.validation</groupId>
             <artifactId>validation-api</artifactId>
             <scope>test</scope>
         </dependency>
+
         <dependency>
             <groupId>org.hibernate</groupId>
             <artifactId>hibernate-validator</artifactId>
             <scope>test</scope>
         </dependency>
+
         <dependency>
             <groupId>org.glassfish</groupId>
             <artifactId>javax.el</artifactId>
             <scope>test</scope>
         </dependency>
+
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-tx</artifactId>
             <scope>test</scope>
         </dependency>
+
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-test</artifactId>
             <scope>test</scope>
         </dependency>
+
         <dependency>
             <groupId>org.apache.tomcat.embed</groupId>
             <artifactId>tomcat-embed-core</artifactId>
             <scope>test</scope>
         </dependency>
+
         <dependency>
             <groupId>org.yaml</groupId>
             <artifactId>snakeyaml</artifactId>
             <scope>test</scope>
         </dependency>
 
+        <!-- Zookeeper -->
+        <dependency>
+            <groupId>org.apache.zookeeper</groupId>
+            <artifactId>zookeeper</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-framework</artifactId>
+            <scope>test</scope>
+        </dependency>
+
     </dependencies>
     <build>
         <plugins>
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AbstractAnnotationConfigBeanBuilder.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AbstractAnnotationConfigBeanBuilder.java
index 7a4129f..0357ff0 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AbstractAnnotationConfigBeanBuilder.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AbstractAnnotationConfigBeanBuilder.java
@@ -30,8 +30,8 @@ import org.springframework.util.Assert;
 import java.lang.annotation.Annotation;
 import java.util.List;
 
-import static com.alibaba.spring.util.BeanFactoryUtils.getBeans;
-import static com.alibaba.spring.util.BeanFactoryUtils.getOptionalBean;
+import static com.alibaba.dubbo.config.spring.util.BeanFactoryUtils.getBeans;
+import static com.alibaba.dubbo.config.spring.util.BeanFactoryUtils.getOptionalBean;
 
 /**
  * Abstract Configurable {@link Annotation} Bean Builder
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationBeanNameBuilder.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationBeanNameBuilder.java
new file mode 100644
index 0000000..cf72a4a
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationBeanNameBuilder.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.config.spring.beans.factory.annotation;
+
+import com.alibaba.dubbo.common.Constants;
+import com.alibaba.dubbo.config.annotation.Reference;
+import com.alibaba.dubbo.config.annotation.Service;
+import com.alibaba.dubbo.registry.Registry;
+
+import org.springframework.core.env.Environment;
+
+import static com.alibaba.dubbo.common.Constants.CONSUMERS_CATEGORY;
+import static com.alibaba.dubbo.common.Constants.DEFAULT_PROTOCOL;
+import static com.alibaba.dubbo.common.Constants.PROVIDERS_CATEGORY;
+import static com.alibaba.dubbo.config.spring.util.AnnotationUtils.resolveInterfaceName;
+import static org.springframework.util.StringUtils.arrayToCommaDelimitedString;
+import static org.springframework.util.StringUtils.hasText;
+
+/**
+ * The Bean Name Builder for the annotations {@link Service} and {@link Reference}
+ * <p>
+ * The naming rule is consistent with the the implementation {@link Registry} that is based on the service-name aware
+ * infrastructure, e.g Spring Cloud, Cloud Native and so on.
+ * <p>
+ * The pattern of bean name : ${category}:${protocol}:${serviceInterface}:${version}:${group}.
+ * <p>
+ * ${version} and ${group} are optional.
+ *
+ * @since 2.6.6
+ */
+class AnnotationBeanNameBuilder {
+
+    private static final String SEPARATOR = ":";
+
+    // Required properties
+
+    private final String category;
+
+    private final String protocol;
+
+    private final String interfaceClassName;
+
+    // Optional properties
+
+    private String version;
+
+    private String group;
+
+    private Environment environment;
+
+    private AnnotationBeanNameBuilder(String category, String protocol, String interfaceClassName) {
+        this.category = category;
+        this.protocol = protocol;
+        this.interfaceClassName = interfaceClassName;
+    }
+
+    private AnnotationBeanNameBuilder(Service service, Class<?> interfaceClass) {
+        this(PROVIDERS_CATEGORY, resolveProtocol(service.protocol()), resolveInterfaceName(service, interfaceClass));
+        this.group(service.group());
+        this.version(service.version());
+    }
+
+    private AnnotationBeanNameBuilder(Reference reference, Class<?> interfaceClass) {
+        this(CONSUMERS_CATEGORY, resolveProtocol(reference.protocol()), resolveInterfaceName(reference, interfaceClass));
+        this.group(reference.group());
+        this.version(reference.version());
+    }
+
+    public static AnnotationBeanNameBuilder create(Service service, Class<?> interfaceClass) {
+        return new AnnotationBeanNameBuilder(service, interfaceClass);
+    }
+
+    public static AnnotationBeanNameBuilder create(Reference reference, Class<?> interfaceClass) {
+        return new AnnotationBeanNameBuilder(reference, interfaceClass);
+    }
+
+    private static void append(StringBuilder builder, String value) {
+        if (hasText(value)) {
+            builder.append(SEPARATOR).append(value);
+        }
+    }
+
+    public AnnotationBeanNameBuilder group(String group) {
+        this.group = group;
+        return this;
+    }
+
+    public AnnotationBeanNameBuilder version(String version) {
+        this.version = version;
+        return this;
+    }
+
+    public AnnotationBeanNameBuilder environment(Environment environment) {
+        this.environment = environment;
+        return this;
+    }
+
+    /**
+     * Resolve the protocol
+     *
+     * @param protocols one or more protocols
+     * @return if <code>protocols</code> == <code>null</code>, it will return
+     * {@link Constants#DEFAULT_PROTOCOL "dubbo"} as the default protocol
+     * @see Constants#DEFAULT_PROTOCOL
+     */
+    private static String resolveProtocol(String... protocols) {
+        String protocol = arrayToCommaDelimitedString(protocols);
+        return hasText(protocol) ? protocol : DEFAULT_PROTOCOL;
+    }
+
+    /**
+     * Build bean name while resolve the placeholders if possible.
+     *
+     * @return pattern : ${category}:${protocol}:${serviceInterface}:${version}:${group}
+     */
+    public String build() {
+        // Append the required properties
+        StringBuilder beanNameBuilder = new StringBuilder(category);
+        append(beanNameBuilder, protocol);
+        append(beanNameBuilder, interfaceClassName);
+        // Append the optional properties
+        append(beanNameBuilder, version);
+        append(beanNameBuilder, group);
+        String beanName = beanNameBuilder.toString();
+        // Resolve placeholders
+        return environment != null ? environment.resolvePlaceholders(beanName) : beanName;
+    }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationInjectedBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationInjectedBeanPostProcessor.java
new file mode 100644
index 0000000..95ecdfb
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationInjectedBeanPostProcessor.java
@@ -0,0 +1,529 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.config.spring.beans.factory.annotation;
+
+import org.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.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.annotation.InjectionMetadata;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+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.EnvironmentAware;
+import org.springframework.core.Ordered;
+import org.springframework.core.PriorityOrdered;
+import org.springframework.core.env.Environment;
+import org.springframework.util.Assert;
+import org.springframework.util.ClassUtils;
+import org.springframework.util.ReflectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.beans.PropertyDescriptor;
+import java.lang.annotation.Annotation;
+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.Collections;
+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 com.alibaba.dubbo.config.spring.util.ClassUtils.resolveGenericType;
+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;
+
+/**
+ * Abstract generic {@link BeanPostProcessor} implementation for customized annotation that annotated injected-object.
+ *
+ * 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
+ *
+ * @since 2.6.6
+ */
+public abstract class AnnotationInjectedBeanPostProcessor<A extends Annotation> extends
+        InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor, PriorityOrdered,
+        BeanFactoryAware, BeanClassLoaderAware, EnvironmentAware, DisposableBean {
+
+    private final static int CACHE_SIZE = Integer.getInteger("", 32);
+
+    private final Log logger = LogFactory.getLog(getClass());
+
+    private final Class<A> annotationType;
+
+    private final ConcurrentMap<String, AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata> injectionMetadataCache =
+            new ConcurrentHashMap<String, AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata>(CACHE_SIZE);
+
+    private final ConcurrentMap<String, Object> injectedObjectsCache = new ConcurrentHashMap<String, Object>(CACHE_SIZE);
+
+    private ConfigurableListableBeanFactory beanFactory;
+
+    private Environment environment;
+
+    private ClassLoader classLoader;
+
+    private int order = Ordered.LOWEST_PRECEDENCE;
+
+    public AnnotationInjectedBeanPostProcessor() {
+        this.annotationType = resolveGenericType(getClass());
+    }
+
+    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;
+    }
+
+    /**
+     * Annotation type
+     *
+     * @return non-null
+     */
+    public final Class<A> getAnnotationType() {
+        return annotationType;
+    }
+
+    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
+        Assert.isInstanceOf(ConfigurableListableBeanFactory.class, beanFactory,
+                "AnnotationInjectedBeanPostProcessor requires a ConfigurableListableBeanFactory");
+        this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
+    }
+
+    @Override
+    public PropertyValues postProcessPropertyValues(
+            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
+
+        InjectionMetadata metadata = findInjectionMetadata(beanName, bean.getClass(), pvs);
+        try {
+            metadata.inject(bean, beanName, pvs);
+        } catch (BeanCreationException ex) {
+            throw ex;
+        } catch (Throwable ex) {
+            throw new BeanCreationException(beanName, "Injection of @" + getAnnotationType().getName()
+                    + " dependencies is failed", ex);
+        }
+        return pvs;
+    }
+
+
+    /**
+     * Finds {@link InjectionMetadata.InjectedElement} Metadata from annotated {@link A} fields
+     *
+     * @param beanClass The {@link Class} of Bean
+     * @return non-null {@link List}
+     */
+    private List<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> findFieldAnnotationMetadata(final Class<?> beanClass) {
+
+        final List<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> elements = new LinkedList<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement>();
+
+        ReflectionUtils.doWithFields(beanClass, new ReflectionUtils.FieldCallback() {
+            @Override
+            public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
+
+                A annotation = getAnnotation(field, getAnnotationType());
+
+                if (annotation != null) {
+
+                    if (Modifier.isStatic(field.getModifiers())) {
+                        if (logger.isWarnEnabled()) {
+                            logger.warn("@" + getAnnotationType().getName() + " is not supported on static fields: " + field);
+                        }
+                        return;
+                    }
+
+                    elements.add(new AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement(field, annotation));
+                }
+
+            }
+        });
+
+        return elements;
+
+    }
+
+    /**
+     * Finds {@link InjectionMetadata.InjectedElement} Metadata from annotated {@link A @A} methods
+     *
+     * @param beanClass The {@link Class} of Bean
+     * @return non-null {@link List}
+     */
+    private List<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> findAnnotatedMethodMetadata(final Class<?> beanClass) {
+
+        final List<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> elements = new LinkedList<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement>();
+
+        ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {
+            @Override
+            public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
+
+                Method bridgedMethod = findBridgedMethod(method);
+
+                if (!isVisibilityBridgeMethodPair(method, bridgedMethod)) {
+                    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);
+                        }
+                        return;
+                    }
+                    if (method.getParameterTypes().length == 0) {
+                        if (logger.isWarnEnabled()) {
+                            logger.warn("@" + getAnnotationType().getSimpleName() + " annotation should only be used on methods with parameters: " +
+                                    method);
+                        }
+                    }
+                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, beanClass);
+                    elements.add(new AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement(method, pd, annotation));
+                }
+            }
+        });
+
+        return elements;
+
+    }
+
+
+    private AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata buildAnnotatedMetadata(final Class<?> beanClass) {
+        Collection<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> fieldElements = findFieldAnnotationMetadata(beanClass);
+        Collection<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> methodElements = findAnnotatedMethodMetadata(beanClass);
+        return new AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata(beanClass, fieldElements, methodElements);
+
+    }
+
+    private InjectionMetadata findInjectionMetadata(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.
+        AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata 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 = buildAnnotatedMetadata(clazz);
+                        this.injectionMetadataCache.put(cacheKey, metadata);
+                    } catch (NoClassDefFoundError err) {
+                        throw new IllegalStateException("Failed to introspect object class [" + clazz.getName() +
+                                "] for annotation metadata: could not find class that it depends on", err);
+                    }
+                }
+            }
+        }
+        return metadata;
+    }
+
+    @Override
+    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
+        if (beanType != null) {
+            InjectionMetadata metadata = findInjectionMetadata(beanName, beanType, null);
+            metadata.checkConfigMembers(beanDefinition);
+        }
+    }
+
+    @Override
+    public int getOrder() {
+        return order;
+    }
+
+    public void setOrder(int order) {
+        this.order = order;
+    }
+
+    @Override
+    public void destroy() throws Exception {
+
+        for (Object object : injectedObjectsCache.values()) {
+            if (logger.isInfoEnabled()) {
+                logger.info(object + " was destroying!");
+            }
+
+            if (object instanceof DisposableBean) {
+                ((DisposableBean) object).destroy();
+            }
+        }
+
+        injectionMetadataCache.clear();
+        injectedObjectsCache.clear();
+
+        if (logger.isInfoEnabled()) {
+            logger.info(getClass() + " was destroying!");
+        }
+
+    }
+
+    @Override
+    public void setBeanClassLoader(ClassLoader classLoader) {
+        this.classLoader = classLoader;
+    }
+
+    public void setEnvironment(Environment environment) {
+        this.environment = environment;
+    }
+
+    protected Environment getEnvironment() {
+        return environment;
+    }
+
+    protected ClassLoader getClassLoader() {
+        return classLoader;
+    }
+
+    protected ConfigurableListableBeanFactory getBeanFactory() {
+        return beanFactory;
+    }
+
+    /**
+     * Gets all injected-objects.
+     *
+     * @return non-null {@link Collection}
+     */
+    protected Collection<Object> getInjectedObjects() {
+        return this.injectedObjectsCache.values();
+    }
+
+    /**
+     * Get injected-object from specified {@link A annotation} and Bean Class
+     *
+     * @param annotation      {@link A annotation}
+     * @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 An injected object
+     * @throws Exception If getting is failed
+     */
+    protected Object getInjectedObject(A annotation, Object bean, String beanName, Class<?> injectedType,
+                                       InjectionMetadata.InjectedElement injectedElement) throws Exception {
+
+        String cacheKey = buildInjectedObjectCacheKey(annotation, bean, beanName, injectedType, injectedElement);
+
+        Object injectedObject = injectedObjectsCache.get(cacheKey);
+
+        if (injectedObject == null) {
+            injectedObject = doGetInjectedBean(annotation, bean, beanName, injectedType, injectedElement);
+            // Customized inject-object if necessary
+            injectedObjectsCache.putIfAbsent(cacheKey, injectedObject);
+        }
+
+        return injectedObject;
+
+    }
+
+    /**
+     * Subclass must implement this method to get injected-object. The context objects could help this method if
+     * necessary :
+     * <ul>
+     * <li>{@link #getBeanFactory() BeanFactory}</li>
+     * <li>{@link #getClassLoader() ClassLoader}</li>
+     * <li>{@link #getEnvironment() Environment}</li>
+     * </ul>
+     *
+     * @param annotation      {@link A annotation}
+     * @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 The injected object
+     * @throws Exception If resolving an injected object is failed.
+     */
+    protected abstract Object doGetInjectedBean(A annotation, Object bean, String beanName, Class<?> injectedType,
+                                                InjectionMetadata.InjectedElement injectedElement) throws Exception;
+
+    /**
+     * Build a cache key for injected-object. The context objects could help this method if
+     * necessary :
+     * <ul>
+     * <li>{@link #getBeanFactory() BeanFactory}</li>
+     * <li>{@link #getClassLoader() ClassLoader}</li>
+     * <li>{@link #getEnvironment() Environment}</li>
+     * </ul>
+     *
+     * @param annotation      {@link A annotation}
+     * @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,
+                                                          Class<?> injectedType,
+                                                          InjectionMetadata.InjectedElement injectedElement);
+
+    /**
+     * Get {@link Map} in injected field.
+     *
+     * @return non-null ready-only {@link Map}
+     */
+    protected Map<InjectionMetadata.InjectedElement, Object> getInjectedFieldObjectsMap() {
+
+        Map<InjectionMetadata.InjectedElement, Object> injectedElementBeanMap =
+                new LinkedHashMap<InjectionMetadata.InjectedElement, Object>();
+
+        for (AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata metadata : injectionMetadataCache.values()) {
+
+            Collection<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> fieldElements = metadata.getFieldElements();
+
+            for (AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement fieldElement : fieldElements) {
+
+                injectedElementBeanMap.put(fieldElement, fieldElement.bean);
+
+            }
+
+        }
+
+        return Collections.unmodifiableMap(injectedElementBeanMap);
+
+    }
+
+    /**
+     * Get {@link Map} in injected method.
+     *
+     * @return non-null {@link Map}
+     */
+    protected Map<InjectionMetadata.InjectedElement, Object> getInjectedMethodObjectsMap() {
+
+        Map<InjectionMetadata.InjectedElement, Object> injectedElementBeanMap =
+                new LinkedHashMap<InjectionMetadata.InjectedElement, Object>();
+
+        for (AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata metadata : injectionMetadataCache.values()) {
+
+            Collection<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> methodElements = metadata.getMethodElements();
+
+            for (AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement methodElement : methodElements) {
+
+                injectedElementBeanMap.put(methodElement, methodElement.object);
+
+            }
+
+        }
+
+        return Collections.unmodifiableMap(injectedElementBeanMap);
+
+    }
+
+    /**
+     * {@link A} {@link InjectionMetadata} implementation
+     */
+    private class AnnotatedInjectionMetadata extends InjectionMetadata {
+
+        private final Collection<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> fieldElements;
+
+        private final Collection<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> methodElements;
+
+        public AnnotatedInjectionMetadata(Class<?> targetClass, Collection<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> fieldElements,
+                                          Collection<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> methodElements) {
+            super(targetClass, combine(fieldElements, methodElements));
+            this.fieldElements = fieldElements;
+            this.methodElements = methodElements;
+        }
+
+        public Collection<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> getFieldElements() {
+            return fieldElements;
+        }
+
+        public Collection<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> getMethodElements() {
+            return methodElements;
+        }
+    }
+
+    /**
+     * {@link A} {@link Method} {@link InjectionMetadata.InjectedElement}
+     */
+    private class AnnotatedMethodElement extends InjectionMetadata.InjectedElement {
+
+        private final Method method;
+
+        private final A annotation;
+
+        private volatile Object object;
+
+        protected AnnotatedMethodElement(Method method, PropertyDescriptor pd, A annotation) {
+            super(method, pd);
+            this.method = method;
+            this.annotation = annotation;
+        }
+
+        @Override
+        protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
+
+            Class<?> injectedType = pd.getPropertyType();
+
+            Object injectedObject = getInjectedObject(annotation, bean, beanName, injectedType, this);
+
+            ReflectionUtils.makeAccessible(method);
+
+            method.invoke(bean, injectedObject);
+
+        }
+
+    }
+
+    /**
+     * {@link A} {@link Field} {@link InjectionMetadata.InjectedElement}
+     */
+    public class AnnotatedFieldElement extends InjectionMetadata.InjectedElement {
+
+        private final Field field;
+
+        private final A annotation;
+
+        private volatile Object bean;
+
+        protected AnnotatedFieldElement(Field field, A annotation) {
+            super(field, null);
+            this.field = field;
+            this.annotation = annotation;
+        }
+
+        @Override
+        protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
+
+            Class<?> injectedType = field.getType();
+
+            Object injectedObject = getInjectedObject(annotation, bean, beanName, injectedType, this);
+
+            ReflectionUtils.makeAccessible(field);
+
+            field.set(bean, injectedObject);
+
+        }
+
+    }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java
index 29a8acc..aab1883 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java
@@ -23,7 +23,7 @@ import org.springframework.core.env.PropertyResolver;
 
 import java.lang.annotation.Annotation;
 
-import static com.alibaba.spring.util.AnnotationUtils.getAttributes;
+import static com.alibaba.dubbo.config.spring.util.AnnotationUtils.getAttributes;
 
 
 /**
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/DubboConfigBindingBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/DubboConfigBindingBeanPostProcessor.java
index 46ace14..f87be24 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/DubboConfigBindingBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/DubboConfigBindingBeanPostProcessor.java
@@ -20,9 +20,9 @@ import com.alibaba.dubbo.common.utils.Assert;
 import com.alibaba.dubbo.config.AbstractConfig;
 import com.alibaba.dubbo.config.spring.context.annotation.DubboConfigBindingRegistrar;
 import com.alibaba.dubbo.config.spring.context.annotation.EnableDubboConfigBinding;
+import com.alibaba.dubbo.config.spring.context.config.DubboConfigBeanCustomizer;
 import com.alibaba.dubbo.config.spring.context.properties.DefaultDubboConfigBinder;
 import com.alibaba.dubbo.config.spring.context.properties.DubboConfigBinder;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.springframework.beans.BeansException;
@@ -30,8 +30,16 @@ import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
+import org.springframework.core.annotation.AnnotationAwareOrderComparator;
 import org.springframework.core.env.Environment;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import static org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors;
+
 /**
  * Dubbo Config Binding {@link BeanPostProcessor}
  *
@@ -62,6 +70,8 @@ public class DubboConfigBindingBeanPostProcessor implements BeanPostProcessor, A
 
     private boolean ignoreInvalidFields = true;
 
+    private List<DubboConfigBeanCustomizer> configBeanCustomizers = Collections.emptyList();
+
     /**
      * @param prefix   the prefix of Configuration Properties
      * @param beanName the binding Bean Name
@@ -80,18 +90,34 @@ public class DubboConfigBindingBeanPostProcessor implements BeanPostProcessor, A
 
             AbstractConfig dubboConfig = (AbstractConfig) bean;
 
-            dubboConfigBinder.bind(prefix, dubboConfig);
+            bind(prefix, dubboConfig);
+
+            customize(beanName, dubboConfig);
 
-            if (log.isInfoEnabled()) {
-                log.info("The properties of bean [name : " + beanName + "] have been binding by prefix of " +
-                        "configuration properties : " + prefix);
-            }
         }
 
         return bean;
 
     }
 
+    private void bind(String prefix, AbstractConfig dubboConfig) {
+
+        dubboConfigBinder.bind(prefix, dubboConfig);
+
+        if (log.isInfoEnabled()) {
+            log.info("The properties of bean [name : " + beanName + "] have been binding by prefix of " +
+                    "configuration properties : " + prefix);
+        }
+    }
+
+    private void customize(String beanName, AbstractConfig dubboConfig) {
+
+        for (DubboConfigBeanCustomizer customizer : configBeanCustomizers) {
+            customizer.customize(beanName, dubboConfig);
+        }
+
+    }
+
     public boolean isIgnoreUnknownFields() {
         return ignoreUnknownFields;
     }
@@ -129,6 +155,14 @@ public class DubboConfigBindingBeanPostProcessor implements BeanPostProcessor, A
     @Override
     public void afterPropertiesSet() throws Exception {
 
+        initDubboConfigBinder();
+
+        initConfigBeanCustomizers();
+
+    }
+
+    private void initDubboConfigBinder() {
+
         if (dubboConfigBinder == null) {
             try {
                 dubboConfigBinder = applicationContext.getBean(DubboConfigBinder.class);
@@ -146,6 +180,16 @@ public class DubboConfigBindingBeanPostProcessor implements BeanPostProcessor, A
 
     }
 
+    private void initConfigBeanCustomizers() {
+
+        Collection<DubboConfigBeanCustomizer> configBeanCustomizers =
+                beansOfTypeIncludingAncestors(applicationContext, DubboConfigBeanCustomizer.class).values();
+
+        this.configBeanCustomizers = new ArrayList<DubboConfigBeanCustomizer>(configBeanCustomizers);
+
+        AnnotationAwareOrderComparator.sort(this.configBeanCustomizers);
+    }
+
     /**
      * Create {@link DubboConfigBinder} instance.
      *
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
index 517c625..e8be4c0 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
@@ -20,8 +20,7 @@ import com.alibaba.dubbo.config.annotation.Reference;
 import com.alibaba.dubbo.config.spring.ReferenceBean;
 import com.alibaba.dubbo.config.spring.ServiceBean;
 import com.alibaba.dubbo.config.spring.context.event.ServiceBeanExportedEvent;
-import com.alibaba.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor;
-import com.alibaba.spring.util.AnnotationUtils;
+import com.alibaba.dubbo.config.spring.util.AnnotationUtils;
 
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.annotation.InjectionMetadata;
@@ -33,6 +32,7 @@ import org.springframework.context.event.ContextRefreshedEvent;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.util.Collection;
@@ -156,7 +156,18 @@ public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBean
 
         @Override
         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-            return method.invoke(bean, args);
+            Object result = null;
+            try {
+                if (bean == null) { // If the bean is not initialized, invoke init()
+                    // issue: https://github.com/apache/incubator-dubbo/issues/3429
+                    init();
+                }
+                result = method.invoke(bean, args);
+            } catch (InvocationTargetException e) {
+                // re-throws the actual Exception.
+                throw e.getTargetException();
+            }
+            return result;
         }
 
         private void init() {
@@ -170,14 +181,16 @@ public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBean
 
         String key = buildReferencedBeanName(reference, injectedType) +
                 "#source=" + (injectedElement.getMember()) +
-                "#attributes=" + AnnotationUtils.getAttributes(reference,getEnvironment(),true);
+                "#attributes=" + AnnotationUtils.getAttributes(reference, getEnvironment(), true);
 
         return key;
     }
 
     private String buildReferencedBeanName(Reference reference, Class<?> injectedType) {
 
-        ServiceBeanNameBuilder builder = ServiceBeanNameBuilder.create(reference, injectedType, getEnvironment());
+        AnnotationBeanNameBuilder builder = AnnotationBeanNameBuilder.create(reference, injectedType);
+
+        builder.environment(getEnvironment());
 
         return getEnvironment().resolvePlaceholders(builder.build());
     }
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java
index 7b5288d..9b92d21 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java
@@ -31,8 +31,8 @@ import org.springframework.validation.DataBinder;
 import java.beans.PropertyEditorSupport;
 import java.util.Map;
 
-import static com.alibaba.spring.util.BeanFactoryUtils.getOptionalBean;
-import static com.alibaba.spring.util.ObjectUtils.of;
+import static com.alibaba.dubbo.config.spring.util.BeanFactoryUtils.getOptionalBean;
+import static com.alibaba.dubbo.config.spring.util.ObjectUtils.of;
 import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
 
 /**
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
index d34b4a6..0c2fc64 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
@@ -57,7 +57,7 @@ import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 
-import static com.alibaba.spring.util.ObjectUtils.of;
+import static com.alibaba.dubbo.config.spring.util.ObjectUtils.of;
 import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
 import static org.springframework.context.annotation.AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR;
 import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
@@ -262,7 +262,7 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr
             registry.registerBeanDefinition(beanName, serviceBeanDefinition);
 
             if (logger.isInfoEnabled()) {
-                logger.warn("The BeanDefinition[" + serviceBeanDefinition +
+                logger.info("The BeanDefinition[" + serviceBeanDefinition +
                         "] of ServiceBean has been registered with name : " + beanName);
             }
 
@@ -289,11 +289,11 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr
      */
     private String generateServiceBeanName(Service service, Class<?> interfaceClass, String annotatedServiceBeanName) {
 
-        ServiceBeanNameBuilder builder = ServiceBeanNameBuilder.create(service, interfaceClass, environment);
+        AnnotationBeanNameBuilder builder = AnnotationBeanNameBuilder.create(service, interfaceClass);
 
+        builder.environment(environment);
 
         return builder.build();
-
     }
 
     private Class<?> resolveServiceInterfaceClass(Class<?> annotatedServiceBeanClass, Service service) {
@@ -315,8 +315,9 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr
         }
 
         if (interfaceClass == null) {
-
-            Class<?>[] allInterfaces = annotatedServiceBeanClass.getInterfaces();
+            // Find all interfaces from the annotated class
+            // To resolve an issue : https://github.com/apache/incubator-dubbo/issues/3251
+            Class<?>[] allInterfaces = ClassUtils.getAllInterfacesForClass(annotatedServiceBeanClass);
 
             if (allInterfaces.length > 0) {
                 interfaceClass = allInterfaces[0];
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilder.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilder.java
index 06b2dfa..4a97a24 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilder.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilder.java
@@ -35,7 +35,9 @@ import static com.alibaba.dubbo.config.spring.util.AnnotationUtils.resolveInterf
  * @see ServiceBean
  * @see ReferenceBean
  * @since 2.6.5
+ * @deprecated {@link AnnotationBeanNameBuilder} as the replacement
  */
+@Deprecated
 class ServiceBeanNameBuilder {
 
     private static final String SEPARATOR = ":";
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingRegistrar.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingRegistrar.java
index 8e8cf20..2f55f29 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingRegistrar.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingRegistrar.java
@@ -18,7 +18,7 @@ package com.alibaba.dubbo.config.spring.context.annotation;
 
 import com.alibaba.dubbo.config.AbstractConfig;
 import com.alibaba.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor;
-
+import com.alibaba.dubbo.config.spring.context.config.NamePropertyDefaultValueDubboConfigBeanCustomizer;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.springframework.beans.factory.config.BeanDefinition;
@@ -41,8 +41,9 @@ import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
 
-import static com.alibaba.spring.util.PropertySourcesUtils.getSubProperties;
-import static com.alibaba.spring.util.PropertySourcesUtils.normalizePrefix;
+import static com.alibaba.dubbo.config.spring.util.BeanRegistrar.registerInfrastructureBean;
+import static com.alibaba.dubbo.config.spring.util.PropertySourcesUtils.getSubProperties;
+import static com.alibaba.dubbo.config.spring.util.PropertySourcesUtils.normalizePrefix;
 import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
 import static org.springframework.beans.factory.support.BeanDefinitionReaderUtils.registerWithGeneratedName;
 
@@ -107,6 +108,8 @@ public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistra
 
         }
 
+        registerDubboConfigBeanCustomizers(registry);
+
     }
 
     private void registerDubboConfigBean(String beanName, Class<? extends AbstractConfig> configClass,
@@ -149,6 +152,11 @@ public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistra
 
     }
 
+    private void registerDubboConfigBeanCustomizers(BeanDefinitionRegistry registry) {
+        registerInfrastructureBean(registry, "namePropertyDefaultValueDubboConfigBeanCustomizer",
+                NamePropertyDefaultValueDubboConfigBeanCustomizer.class);
+    }
+
     @Override
     public void setEnvironment(Environment environment) {
 
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigConfigurationSelector.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigConfigurationRegistrar.java
similarity index 63%
rename from dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigConfigurationSelector.java
rename to dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigConfigurationRegistrar.java
index 24f581b..ff20d8d 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigConfigurationSelector.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigConfigurationRegistrar.java
@@ -18,43 +18,38 @@ package com.alibaba.dubbo.config.spring.context.annotation;
 
 import com.alibaba.dubbo.config.AbstractConfig;
 
-import org.springframework.context.annotation.ImportSelector;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
 import org.springframework.core.Ordered;
 import org.springframework.core.annotation.AnnotationAttributes;
 import org.springframework.core.type.AnnotationMetadata;
 
+import static com.alibaba.dubbo.config.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans;
+
+
 /**
- * Dubbo {@link AbstractConfig Config} Registrar
+ * Dubbo {@link AbstractConfig Config} {@link ImportBeanDefinitionRegistrar register}
  *
  * @see EnableDubboConfig
  * @see DubboConfigConfiguration
+ * @see Ordered
  * @since 2.5.8
  */
-public class DubboConfigConfigurationSelector implements ImportSelector, Ordered {
+public class DubboConfigConfigurationRegistrar implements ImportBeanDefinitionRegistrar {
 
     @Override
-    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
+    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
 
         AnnotationAttributes attributes = AnnotationAttributes.fromMap(
                 importingClassMetadata.getAnnotationAttributes(EnableDubboConfig.class.getName()));
 
         boolean multiple = attributes.getBoolean("multiple");
 
-        if (multiple) {
-            return of(DubboConfigConfiguration.Multiple.class.getName());
-        } else {
-            return of(DubboConfigConfiguration.Single.class.getName());
-        }
-    }
-
-    private static <T> T[] of(T... values) {
-        return values;
-    }
+        // Single Config Bindings
+        registerBeans(registry, DubboConfigConfiguration.Single.class);
 
-    @Override
-    public int getOrder() {
-        return HIGHEST_PRECEDENCE;
+        if (multiple) { // Since 2.6.6 https://github.com/apache/incubator-dubbo/issues/3193
+            registerBeans(registry, DubboConfigConfiguration.Multiple.class);
+        }
     }
-
-
-}
+}
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubbo.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubbo.java
index 25d8cad..fff2fc4 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubbo.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubbo.java
@@ -76,6 +76,6 @@ public @interface EnableDubbo {
      * @see EnableDubboConfig#multiple()
      */
     @AliasFor(annotation = EnableDubboConfig.class, attribute = "multiple")
-    boolean multipleConfig() default false;
+    boolean multipleConfig() default true;
 
 }
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboConfig.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboConfig.java
index fe20770..ad394f7 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboConfig.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboConfig.java
@@ -46,7 +46,7 @@ import java.lang.annotation.Target;
  * <li>{@link ConsumerConfig} binding to property :  "dubbo.consumer"</li>
  * </ul>
  * <p>
- * In contrast, on multiple bean bindings that requires to set {@link #multiple()} to be <code>true</code> :
+ * On multiple bean bindings that requires to set {@link #multiple()} to be <code>true</code> :
  * <ul>
  * <li>{@link ApplicationConfig} binding to property : "dubbo.applications"</li>
  * <li>{@link ModuleConfig} binding to property :  "dubbo.modules"</li>
@@ -59,22 +59,25 @@ import java.lang.annotation.Target;
  *
  * @see EnableDubboConfigBinding
  * @see DubboConfigConfiguration
- * @see DubboConfigConfigurationSelector
+ * @see DubboConfigConfigurationRegistrar
  * @since 2.5.8
  */
 @Target({ElementType.TYPE})
 @Retention(RetentionPolicy.RUNTIME)
 @Inherited
 @Documented
-@Import(DubboConfigConfigurationSelector.class)
+@Import(DubboConfigConfigurationRegistrar.class)
 public @interface EnableDubboConfig {
 
     /**
      * It indicates whether binding to multiple Spring Beans.
+     * <p>
+     * Please note that if {@link #multiple()} is <code>true</code> since 2.6.6, the multiple bean bindings will be
+     * enabled, works with single bean bindings, rather than they are mutually exclusive before.
      *
-     * @return the default value is <code>false</code>
+     * @return the default value is <code>true</code> since 2.6.6, the value is inverse earlier.
      * @revised 2.5.9
      */
-    boolean multiple() default false;
+    boolean multiple() default true;
 
 }
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/config/DubboConfigBeanCustomizer.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/config/DubboConfigBeanCustomizer.java
new file mode 100644
index 0000000..42e1f6a
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/config/DubboConfigBeanCustomizer.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.config.spring.context.config;
+
+import com.alibaba.dubbo.config.AbstractConfig;
+import com.alibaba.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor;
+import com.alibaba.dubbo.config.spring.context.properties.DubboConfigBinder;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.Ordered;
+
+/**
+ * The Bean customizer for {@link AbstractConfig Dubbo Config}. Generally, The subclass will be  registered as a Spring
+ * Bean that is used to {@link #customize(String, AbstractConfig) customize} {@link AbstractConfig Dubbo Config} bean
+ * after {@link DubboConfigBinder#bind(String, AbstractConfig) its binding}.
+ * <p>
+ * If There are multiple {@link DubboConfigBeanCustomizer} beans in the Spring {@link ApplicationContext context}, they
+ * are executed orderly, thus the subclass should be aware to implement the {@link #getOrder()} method.
+ *
+ * @see DubboConfigBinder#bind(String, AbstractConfig)
+ * @see DubboConfigBindingBeanPostProcessor
+ * @since 2.6.6
+ */
+public interface DubboConfigBeanCustomizer extends Ordered {
+
+    /**
+     * Customize {@link AbstractConfig Dubbo Config Bean}
+     *
+     * @param beanName        the name of {@link AbstractConfig Dubbo Config Bean}
+     * @param dubboConfigBean the instance of {@link AbstractConfig Dubbo Config Bean}
+     */
+    void customize(String beanName, AbstractConfig dubboConfigBean);
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/config/NamePropertyDefaultValueDubboConfigBeanCustomizer.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/config/NamePropertyDefaultValueDubboConfigBeanCustomizer.java
new file mode 100644
index 0000000..d938218
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/config/NamePropertyDefaultValueDubboConfigBeanCustomizer.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.config.spring.context.config;
+
+import com.alibaba.dubbo.config.AbstractConfig;
+import org.springframework.util.ReflectionUtils;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+import static com.alibaba.dubbo.config.spring.util.ObjectUtils.of;
+import static org.springframework.beans.BeanUtils.getPropertyDescriptor;
+
+/**
+ * {@link DubboConfigBeanCustomizer} for the default value for the "name" property that will be taken bean name
+ * if absent.
+ *
+ * @since 2.6.6
+ */
+public class NamePropertyDefaultValueDubboConfigBeanCustomizer implements DubboConfigBeanCustomizer {
+
+    /**
+     * The name of property that is "name" maybe is absent in target class
+     */
+    private static final String PROPERTY_NAME = "name";
+
+    @Override
+    public void customize(String beanName, AbstractConfig dubboConfigBean) {
+
+        PropertyDescriptor propertyDescriptor = getPropertyDescriptor(dubboConfigBean.getClass(), PROPERTY_NAME);
+
+        if (propertyDescriptor != null) { // "name" property is present
+
+            Method getNameMethod = propertyDescriptor.getReadMethod();
+
+            if (getNameMethod == null) { // if "getName" method is absent
+                return;
+            }
+
+            Object propertyValue = ReflectionUtils.invokeMethod(getNameMethod, dubboConfigBean);
+
+            if (propertyValue != null) { // If The return value of "getName" method is not null
+                return;
+            }
+
+            Method setNameMethod = propertyDescriptor.getWriteMethod();
+            if (setNameMethod != null && getNameMethod != null) { // "setName" and "getName" methods are present
+                if (Arrays.equals(of(String.class), setNameMethod.getParameterTypes())) { // the param type is String
+                    // set bean name to the value of the "name" property
+                    ReflectionUtils.invokeMethod(setNameMethod, dubboConfigBean, beanName);
+                }
+            }
+        }
+    }
+
+    @Override
+    public int getOrder() {
+        return HIGHEST_PRECEDENCE;
+    }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/properties/DefaultDubboConfigBinder.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/properties/DefaultDubboConfigBinder.java
index 045a5ac..cda2a6e 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/properties/DefaultDubboConfigBinder.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/context/properties/DefaultDubboConfigBinder.java
@@ -23,7 +23,7 @@ import org.springframework.validation.DataBinder;
 
 import java.util.Map;
 
-import static com.alibaba.spring.util.PropertySourcesUtils.getSubProperties;
+import static com.alibaba.dubbo.config.spring.util.PropertySourcesUtils.getSubProperties;
 
 /**
  * Default {@link DubboConfigBinder} implementation based on Spring {@link DataBinder}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactory.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactory.java
index 5cbc06e..c6a07de 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactory.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactory.java
@@ -1,111 +1,111 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.alibaba.dubbo.config.spring.extension;
-
-import com.alibaba.dubbo.common.extension.ExtensionFactory;
-import com.alibaba.dubbo.common.logger.Logger;
-import com.alibaba.dubbo.common.logger.LoggerFactory;
-import com.alibaba.dubbo.common.utils.ConcurrentHashSet;
-
-import com.alibaba.dubbo.config.DubboShutdownHook;
-import com.alibaba.dubbo.config.spring.util.BeanFactoryUtils;
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
-import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationEvent;
-import org.springframework.context.ApplicationListener;
-import org.springframework.context.event.ContextClosedEvent;
-
-import java.util.Set;
-
-/**
- * SpringExtensionFactory
- */
-public class SpringExtensionFactory implements ExtensionFactory {
-    private static final Logger logger = LoggerFactory.getLogger(SpringExtensionFactory.class);
-
-    private static final Set<ApplicationContext> contexts = new ConcurrentHashSet<ApplicationContext>();
-
-    private static final ApplicationListener shutdownHookListener = new ShutdownHookListener();
-
-    public static void addApplicationContext(ApplicationContext context) {
-        contexts.add(context);
-        BeanFactoryUtils.addApplicationListener(context, shutdownHookListener);
-    }
-
-    public static void removeApplicationContext(ApplicationContext context) {
-        contexts.remove(context);
-    }
-
-    public static Set<ApplicationContext> getContexts() {
-        return contexts;
-    }
-
-    // currently for test purpose
-    public static void clearContexts() {
-        contexts.clear();
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <T> T getExtension(Class<T> type, String name) {
-        for (ApplicationContext context : contexts) {
-            if (context.containsBean(name)) {
-                Object bean = context.getBean(name);
-                if (type.isInstance(bean)) {
-                    return (T) bean;
-                }
-            }
-        }
-
-        logger.warn("No spring extension (bean) named:" + name + ", try to find an extension (bean) of type " + type.getName());
-
-        if (Object.class == type) {
-            return null;
-        }
-
-        for (ApplicationContext context : contexts) {
-            try {
-                return context.getBean(type);
-            } catch (NoUniqueBeanDefinitionException multiBeanExe) {
-                logger.warn("Find more than 1 spring extensions (beans) of type " + type.getName() + ", will stop auto injection. Please make sure you have specified the concrete parameter type and there's only one extension of that type.");
-            } catch (NoSuchBeanDefinitionException noBeanExe) {
-                if (logger.isDebugEnabled()) {
-                    logger.debug("Error when get spring extension(bean) for type:" + type.getName(), noBeanExe);
-                }
-            }
-        }
-
-        logger.warn("No spring extension (bean) named:" + name + ", type:" + type.getName() + " found, stop get bean.");
-
-        return null;
-    }
-
-    private static class ShutdownHookListener implements ApplicationListener {
-        @Override
-        public void onApplicationEvent(ApplicationEvent event) {
-            if (event instanceof ContextClosedEvent) {
-                // we call it anyway since dubbo shutdown hook make sure its destroyAll() is re-entrant.
-                // pls. note we should not remove dubbo shutdown hook when spring framework is present, this is because
-                // its shutdown hook may not be installed.
-                DubboShutdownHook shutdownHook = DubboShutdownHook.getDubboShutdownHook();
-                shutdownHook.destroyAll();
-            }
-        }
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.config.spring.extension;
+
+import com.alibaba.dubbo.common.extension.ExtensionFactory;
+import com.alibaba.dubbo.common.logger.Logger;
+import com.alibaba.dubbo.common.logger.LoggerFactory;
+import com.alibaba.dubbo.common.utils.ConcurrentHashSet;
+import com.alibaba.dubbo.config.DubboShutdownHook;
+import com.alibaba.dubbo.config.spring.util.BeanFactoryUtils;
+
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextClosedEvent;
+
+import java.util.Set;
+
+/**
+ * SpringExtensionFactory
+ */
+public class SpringExtensionFactory implements ExtensionFactory {
+    private static final Logger logger = LoggerFactory.getLogger(SpringExtensionFactory.class);
+
+    private static final Set<ApplicationContext> contexts = new ConcurrentHashSet<ApplicationContext>();
+
+    private static final ApplicationListener shutdownHookListener = new ShutdownHookListener();
+
+    public static void addApplicationContext(ApplicationContext context) {
+        contexts.add(context);
+        BeanFactoryUtils.addApplicationListener(context, shutdownHookListener);
+    }
+
+    public static void removeApplicationContext(ApplicationContext context) {
+        contexts.remove(context);
+    }
+
+    public static Set<ApplicationContext> getContexts() {
+        return contexts;
+    }
+
+    // currently for test purpose
+    public static void clearContexts() {
+        contexts.clear();
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <T> T getExtension(Class<T> type, String name) {
+        for (ApplicationContext context : contexts) {
+            if (context.containsBean(name)) {
+                Object bean = context.getBean(name);
+                if (type.isInstance(bean)) {
+                    return (T) bean;
+                }
+            }
+        }
+
+        logger.warn("No spring extension (bean) named:" + name + ", try to find an extension (bean) of type " + type.getName());
+
+        if (Object.class == type) {
+            return null;
+        }
+
+        for (ApplicationContext context : contexts) {
+            try {
+                return context.getBean(type);
+            } catch (NoUniqueBeanDefinitionException multiBeanExe) {
+                logger.warn("Find more than 1 spring extensions (beans) of type " + type.getName() + ", will stop auto injection. Please make sure you have specified the concrete parameter type and there's only one extension of that type.");
+            } catch (NoSuchBeanDefinitionException noBeanExe) {
+                if (logger.isDebugEnabled()) {
+                    logger.debug("Error when get spring extension(bean) for type:" + type.getName(), noBeanExe);
+                }
+            }
+        }
+
+        logger.warn("No spring extension (bean) named:" + name + ", type:" + type.getName() + " found, stop get bean.");
+
+        return null;
+    }
+
+    private static class ShutdownHookListener implements ApplicationListener {
+        @Override
+        public void onApplicationEvent(ApplicationEvent event) {
+            if (event instanceof ContextClosedEvent) {
+                // we call it anyway since dubbo shutdown hook make sure its destroyAll() is re-entrant.
+                // pls. note we should not remove dubbo shutdown hook when spring framework is present, this is because
+                // its shutdown hook may not be installed.
+                DubboShutdownHook shutdownHook = DubboShutdownHook.getDubboShutdownHook();
+                shutdownHook.destroyAll();
+            }
+        }
+    }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/status/DataSourceStatusChecker.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/status/DataSourceStatusChecker.java
index 32baa41..8863d8b 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/status/DataSourceStatusChecker.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/status/DataSourceStatusChecker.java
@@ -1,96 +1,96 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.alibaba.dubbo.config.spring.status;
-
-import com.alibaba.dubbo.common.extension.Activate;
-import com.alibaba.dubbo.common.logger.Logger;
-import com.alibaba.dubbo.common.logger.LoggerFactory;
-import com.alibaba.dubbo.common.status.Status;
-import com.alibaba.dubbo.common.status.StatusChecker;
-
-import com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory;
-import org.springframework.context.ApplicationContext;
-
-import javax.sql.DataSource;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.ResultSet;
-import java.util.Map;
-
-/**
- * DataSourceStatusChecker
- */
-@Activate
-public class DataSourceStatusChecker implements StatusChecker {
-
-    private static final Logger logger = LoggerFactory.getLogger(DataSourceStatusChecker.class);
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public Status check() {
-        ApplicationContext context = null;
-        for (ApplicationContext c : SpringExtensionFactory.getContexts()) {
-            if (c != null) {
-                context = c;
-                break;
-            }
-        }
-        if (context == null) {
-            return new Status(Status.Level.UNKNOWN);
-        }
-        Map<String, DataSource> dataSources = context.getBeansOfType(DataSource.class, false, false);
-        if (dataSources == null || dataSources.size() == 0) {
-            return new Status(Status.Level.UNKNOWN);
-        }
-        Status.Level level = Status.Level.OK;
-        StringBuilder buf = new StringBuilder();
-        for (Map.Entry<String, DataSource> entry : dataSources.entrySet()) {
-            DataSource dataSource = entry.getValue();
-            if (buf.length() > 0) {
-                buf.append(", ");
-            }
-            buf.append(entry.getKey());
-            try {
-                Connection connection = dataSource.getConnection();
-                try {
-                    DatabaseMetaData metaData = connection.getMetaData();
-                    ResultSet resultSet = metaData.getTypeInfo();
-                    try {
-                        if (!resultSet.next()) {
-                            level = Status.Level.ERROR;
-                        }
-                    } finally {
-                        resultSet.close();
-                    }
-                    buf.append(metaData.getURL());
-                    buf.append("(");
-                    buf.append(metaData.getDatabaseProductName());
-                    buf.append("-");
-                    buf.append(metaData.getDatabaseProductVersion());
-                    buf.append(")");
-                } finally {
-                    connection.close();
-                }
-            } catch (Throwable e) {
-                logger.warn(e.getMessage(), e);
-                return new Status(level, e.getMessage());
-            }
-        }
-        return new Status(level, buf.toString());
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.config.spring.status;
+
+import com.alibaba.dubbo.common.extension.Activate;
+import com.alibaba.dubbo.common.logger.Logger;
+import com.alibaba.dubbo.common.logger.LoggerFactory;
+import com.alibaba.dubbo.common.status.Status;
+import com.alibaba.dubbo.common.status.StatusChecker;
+import com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory;
+
+import org.springframework.context.ApplicationContext;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.util.Map;
+
+/**
+ * DataSourceStatusChecker
+ */
+@Activate
+public class DataSourceStatusChecker implements StatusChecker {
+
+    private static final Logger logger = LoggerFactory.getLogger(DataSourceStatusChecker.class);
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Status check() {
+        ApplicationContext context = null;
+        for (ApplicationContext c : SpringExtensionFactory.getContexts()) {
+            if (c != null) {
+                context = c;
+                break;
+            }
+        }
+        if (context == null) {
+            return new Status(Status.Level.UNKNOWN);
+        }
+        Map<String, DataSource> dataSources = context.getBeansOfType(DataSource.class, false, false);
+        if (dataSources == null || dataSources.size() == 0) {
+            return new Status(Status.Level.UNKNOWN);
+        }
+        Status.Level level = Status.Level.OK;
+        StringBuilder buf = new StringBuilder();
+        for (Map.Entry<String, DataSource> entry : dataSources.entrySet()) {
+            DataSource dataSource = entry.getValue();
+            if (buf.length() > 0) {
+                buf.append(", ");
+            }
+            buf.append(entry.getKey());
+            try {
+                Connection connection = dataSource.getConnection();
+                try {
+                    DatabaseMetaData metaData = connection.getMetaData();
+                    ResultSet resultSet = metaData.getTypeInfo();
+                    try {
+                        if (!resultSet.next()) {
+                            level = Status.Level.ERROR;
+                        }
+                    } finally {
+                        resultSet.close();
+                    }
+                    buf.append(metaData.getURL());
+                    buf.append("(");
+                    buf.append(metaData.getDatabaseProductName());
+                    buf.append("-");
+                    buf.append(metaData.getDatabaseProductVersion());
+                    buf.append(")");
+                } finally {
+                    connection.close();
+                }
+            } catch (Throwable e) {
+                logger.warn(e.getMessage(), e);
+                return new Status(level, e.getMessage());
+            }
+        }
+        return new Status(level, buf.toString());
+    }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/status/SpringStatusChecker.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/status/SpringStatusChecker.java
index f80b5e6..282f364 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/status/SpringStatusChecker.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/status/SpringStatusChecker.java
@@ -1,92 +1,92 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.alibaba.dubbo.config.spring.status;
-
-import com.alibaba.dubbo.common.extension.Activate;
-import com.alibaba.dubbo.common.logger.Logger;
-import com.alibaba.dubbo.common.logger.LoggerFactory;
-import com.alibaba.dubbo.common.status.Status;
-import com.alibaba.dubbo.common.status.StatusChecker;
-
-import com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.Lifecycle;
-
-import java.lang.reflect.Method;
-
-/**
- * SpringStatusChecker
- */
-@Activate
-public class SpringStatusChecker implements StatusChecker {
-
-    private static final Logger logger = LoggerFactory.getLogger(SpringStatusChecker.class);
-
-    @Override
-    public Status check() {
-        ApplicationContext context = null;
-        for (ApplicationContext c : SpringExtensionFactory.getContexts()) {
-            if (c != null) {
-                context = c;
-                break;
-            }
-        }
-        if (context == null) {
-            return new Status(Status.Level.UNKNOWN);
-        }
-        Status.Level level = Status.Level.OK;
-        if (context instanceof Lifecycle) {
-            if (((Lifecycle) context).isRunning()) {
-                level = Status.Level.OK;
-            } else {
-                level = Status.Level.ERROR;
-            }
-        } else {
-            level = Status.Level.UNKNOWN;
-        }
-        StringBuilder buf = new StringBuilder();
-        try {
-            Class<?> cls = context.getClass();
-            Method method = null;
-            while (cls != null && method == null) {
-                try {
-                    method = cls.getDeclaredMethod("getConfigLocations", new Class<?>[0]);
-                } catch (NoSuchMethodException t) {
-                    cls = cls.getSuperclass();
-                }
-            }
-            if (method != null) {
-                if (!method.isAccessible()) {
-                    method.setAccessible(true);
-                }
-                String[] configs = (String[]) method.invoke(context, new Object[0]);
-                if (configs != null && configs.length > 0) {
-                    for (String config : configs) {
-                        if (buf.length() > 0) {
-                            buf.append(",");
-                        }
-                        buf.append(config);
-                    }
-                }
-            }
-        } catch (Throwable t) {
-            logger.warn(t.getMessage(), t);
-        }
-        return new Status(level, buf.toString());
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.config.spring.status;
+
+import com.alibaba.dubbo.common.extension.Activate;
+import com.alibaba.dubbo.common.logger.Logger;
+import com.alibaba.dubbo.common.logger.LoggerFactory;
+import com.alibaba.dubbo.common.status.Status;
+import com.alibaba.dubbo.common.status.StatusChecker;
+import com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.Lifecycle;
+
+import java.lang.reflect.Method;
+
+/**
+ * SpringStatusChecker
+ */
+@Activate
+public class SpringStatusChecker implements StatusChecker {
+
+    private static final Logger logger = LoggerFactory.getLogger(SpringStatusChecker.class);
+
+    @Override
+    public Status check() {
+        ApplicationContext context = null;
+        for (ApplicationContext c : SpringExtensionFactory.getContexts()) {
+            if (c != null) {
+                context = c;
+                break;
+            }
+        }
+        if (context == null) {
+            return new Status(Status.Level.UNKNOWN);
+        }
+        Status.Level level = Status.Level.OK;
+        if (context instanceof Lifecycle) {
+            if (((Lifecycle) context).isRunning()) {
+                level = Status.Level.OK;
+            } else {
+                level = Status.Level.ERROR;
+            }
+        } else {
+            level = Status.Level.UNKNOWN;
+        }
+        StringBuilder buf = new StringBuilder();
+        try {
+            Class<?> cls = context.getClass();
+            Method method = null;
+            while (cls != null && method == null) {
+                try {
+                    method = cls.getDeclaredMethod("getConfigLocations", new Class<?>[0]);
+                } catch (NoSuchMethodException t) {
+                    cls = cls.getSuperclass();
+                }
+            }
+            if (method != null) {
+                if (!method.isAccessible()) {
+                    method.setAccessible(true);
+                }
+                String[] configs = (String[]) method.invoke(context, new Object[0]);
+                if (configs != null && configs.length > 0) {
+                    for (String config : configs) {
+                        if (buf.length() > 0) {
+                            buf.append(",");
+                        }
+                        buf.append(config);
+                    }
+                }
+            }
+        } catch (Throwable t) {
+            logger.warn(t.getMessage(), t);
+        }
+        return new Status(level, buf.toString());
+    }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtils.java
new file mode 100644
index 0000000..ccc3427
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtils.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.config.spring.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
+import org.springframework.util.ObjectUtils;
+
+import java.lang.annotation.Annotation;
+import java.util.Arrays;
+
+/**
+ * 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 {
+
+    private static final Log logger = LogFactory.getLog(AnnotatedBeanDefinitionRegistryUtils.class);
+
+    /**
+     * Register Beans
+     *
+     * @param registry         {@link BeanDefinitionRegistry}
+     * @param annotatedClasses {@link Annotation annotation} class
+     */
+    public static void registerBeans(BeanDefinitionRegistry registry, Class<?>... annotatedClasses) {
+
+        if (ObjectUtils.isEmpty(annotatedClasses)) {
+            return;
+        }
+
+        boolean debugEnabled = logger.isDebugEnabled();
+
+        AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(registry);
+
+        if (debugEnabled) {
+            logger.debug(registry.getClass().getSimpleName() + " will register annotated classes : " + Arrays.asList(annotatedClasses) + " .");
+        }
+
+        reader.register(annotatedClasses);
+
+    }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/AnnotationUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/AnnotationUtils.java
index 7e5bb49..703e649 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/AnnotationUtils.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/AnnotationUtils.java
@@ -19,15 +19,39 @@ package com.alibaba.dubbo.config.spring.util;
 import com.alibaba.dubbo.config.annotation.Reference;
 import com.alibaba.dubbo.config.annotation.Service;
 
+import org.springframework.core.env.Environment;
+import org.springframework.core.env.PropertyResolver;
 import org.springframework.util.StringUtils;
 
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+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 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.CollectionUtils.arrayToList;
+import static org.springframework.util.ObjectUtils.nullSafeEquals;
+import static org.springframework.util.StringUtils.trimWhitespace;
+
 /**
  * Annotation Utilities Class
  *
  * @see org.springframework.core.annotation.AnnotationUtils
  * @since 2.5.11
  */
-public class AnnotationUtils {
+public abstract class AnnotationUtils {
 
     public static String resolveInterfaceName(Service service, Class<?> defaultInterfaceClass)
             throws IllegalStateException {
@@ -69,4 +93,192 @@ public class AnnotationUtils {
 
     }
 
+
+    // Cloned from https://github.com/alibaba/spring-context-support/blob/1.0.2/src/main/java/com/alibaba/spring/util/AnnotationUtils.java
+
+    /**
+     * Is specified {@link Annotation} present on {@link Method}'s declaring class or parameters or itself.
+     *
+     * @param method          {@link Method}
+     * @param annotationClass {@link Annotation} type
+     * @param <A>             {@link Annotation} type
+     * @return If present , return <code>true</code> , or <code>false</code>
+     * @since 2.6.6
+     */
+    public static <A extends Annotation> boolean isPresent(Method method, Class<A> annotationClass) {
+
+        Map<ElementType, List<A>> annotationsMap = findAnnotations(method, annotationClass);
+
+        return !annotationsMap.isEmpty();
+
+    }
+
+    /**
+     * Find specified {@link Annotation} type maps from {@link Method}
+     *
+     * @param method          {@link Method}
+     * @param annotationClass {@link Annotation} type
+     * @param <A>             {@link Annotation} type
+     * @return {@link Annotation} type maps , the {@link ElementType} as key ,
+     * the list of {@link Annotation} as value.
+     * If {@link Annotation} was annotated on {@link Method}'s parameters{@link ElementType#PARAMETER} ,
+     * the associated {@link Annotation} list may contain multiple elements.
+     * @since 2.6.6
+     */
+    public static <A extends Annotation> Map<ElementType, List<A>> findAnnotations(Method method,
+                                                                                   Class<A> annotationClass) {
+
+        Retention retention = annotationClass.getAnnotation(Retention.class);
+
+        RetentionPolicy retentionPolicy = retention.value();
+
+        if (!RetentionPolicy.RUNTIME.equals(retentionPolicy)) {
+            return Collections.emptyMap();
+        }
+
+        Map<ElementType, List<A>> annotationsMap = new LinkedHashMap<ElementType, List<A>>();
+
+        Target target = annotationClass.getAnnotation(Target.class);
+
+        ElementType[] elementTypes = target.value();
+
+
+        for (ElementType elementType : elementTypes) {
+
+            List<A> annotationsList = new LinkedList<A>();
+
+            switch (elementType) {
+
+                case PARAMETER:
+
+                    Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+
+                    for (Annotation[] annotations : parameterAnnotations) {
+
+                        for (Annotation annotation : annotations) {
+
+                            if (annotationClass.equals(annotation.annotationType())) {
+
+                                annotationsList.add((A) annotation);
+
+                            }
+
+                        }
+
+                    }
+
+                    break;
+
+                case METHOD:
+
+                    A annotation = findAnnotation(method, annotationClass);
+
+                    if (annotation != null) {
+
+                        annotationsList.add(annotation);
+
+                    }
+
+                    break;
+
+                case TYPE:
+
+                    Class<?> beanType = method.getDeclaringClass();
+
+                    A annotation2 = findAnnotation(beanType, annotationClass);
+
+                    if (annotation2 != null) {
+
+                        annotationsList.add(annotation2);
+
+                    }
+
+                    break;
+
+            }
+
+            if (!annotationsList.isEmpty()) {
+
+                annotationsMap.put(elementType, annotationsList);
+
+            }
+
+
+        }
+
+        return Collections.unmodifiableMap(annotationsMap);
+
+    }
+
+    /**
+     * Get the {@link Annotation} attributes
+     *
+     * @param annotation           specified {@link Annotation}
+     * @param ignoreDefaultValue   whether ignore default value or not
+     * @param ignoreAttributeNames the attribute names of annotation should be ignored
+     * @return non-null
+     * @since 2.6.6
+     */
+    public static Map<String, Object> getAttributes(Annotation annotation, boolean ignoreDefaultValue,
+                                                    String... ignoreAttributeNames) {
+        return getAttributes(annotation, null, ignoreDefaultValue, ignoreAttributeNames);
+    }
+
+    /**
+     * Get the {@link Annotation} attributes
+     *
+     * @param annotation           specified {@link 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.6.6
+     */
+    public static Map<String, Object> getAttributes(Annotation annotation, PropertyResolver propertyResolver,
+                                                    boolean ignoreDefaultValue, String... ignoreAttributeNames) {
+
+        Set<String> ignoreAttributeNamesSet = new HashSet<String>(arrayToList(ignoreAttributeNames));
+
+        Map<String, Object> attributes = getAnnotationAttributes(annotation);
+
+        Map<String, Object> actualAttributes = new LinkedHashMap<String, Object>();
+
+        for (Map.Entry<String, Object> entry : attributes.entrySet()) {
+
+            String attributeName = entry.getKey();
+            Object attributeValue = entry.getValue();
+
+            // ignore default attribute value
+            if (ignoreDefaultValue && nullSafeEquals(attributeValue, getDefaultValue(annotation, attributeName))) {
+                continue;
+            }
+
+            // ignore attribute name
+            if (ignoreAttributeNamesSet.contains(attributeName)) {
+                continue;
+            }
+
+            if (attributeValue instanceof String) {
+                attributeValue = resolvePlaceholders(valueOf(attributeValue), propertyResolver);
+            } else if (attributeValue instanceof String[]) {
+                String[] values = (String[]) attributeValue;
+                for (int i = 0; i < values.length; i++) {
+                    values[i] = resolvePlaceholders(values[i], propertyResolver);
+                }
+                attributeValue = values;
+            }
+            actualAttributes.put(attributeName, attributeValue);
+        }
+        return actualAttributes;
+    }
+
+    private static String resolvePlaceholders(String attributeValue, PropertyResolver propertyResolver) {
+        String resolvedValue = attributeValue;
+        if (propertyResolver != null) {
+            resolvedValue = propertyResolver.resolvePlaceholders(resolvedValue);
+            resolvedValue = trimWhitespace(resolvedValue);
+        }
+        return resolvedValue;
+    }
+
 }
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/BeanFactoryUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/BeanFactoryUtils.java
index 13a3011..9018fdd 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/BeanFactoryUtils.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/BeanFactoryUtils.java
@@ -17,12 +17,21 @@
 package com.alibaba.dubbo.config.spring.util;
 
 import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.ListableBeanFactory;
 import org.springframework.beans.factory.config.ConfigurableBeanFactory;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationListener;
 import org.springframework.context.support.AbstractApplicationContext;
 
 import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static org.springframework.beans.factory.BeanFactoryUtils.beanNamesForTypeIncludingAncestors;
+import static org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors;
+import static org.springframework.util.ObjectUtils.containsElement;
 
 /**
  * {@link BeanFactory} Utilities class
@@ -31,7 +40,8 @@ import java.lang.reflect.Method;
  * @see ConfigurableBeanFactory
  * @see org.springframework.beans.factory.BeanFactoryUtils
  */
-public class BeanFactoryUtils {
+public abstract class BeanFactoryUtils {
+
     public static boolean addApplicationListener(ApplicationContext applicationContext, ApplicationListener listener) {
         try {
             // backward compatibility to spring 2.0.1
@@ -55,4 +65,55 @@ public class BeanFactoryUtils {
         }
         return false;
     }
+
+    /**
+     * Get optional Bean
+     *
+     * @param beanFactory {@link ListableBeanFactory}
+     * @param beanName    the name of Bean
+     * @param beanType    the {@link Class type} of Bean
+     * @param <T>         the {@link Class type} of Bean
+     * @return A bean if present , or <code>null</code>
+     * @since 2.6.6
+     */
+    public static <T> T getOptionalBean(ListableBeanFactory beanFactory, String beanName, Class<T> beanType) {
+
+        String[] allBeanNames = beanNamesForTypeIncludingAncestors(beanFactory, beanType);
+
+        if (!containsElement(allBeanNames, beanName)) {
+            return null;
+        }
+
+        Map<String, T> beansOfType = beansOfTypeIncludingAncestors(beanFactory, beanType);
+
+        return beansOfType.get(beanName);
+
+    }
+
+
+    /**
+     * Gets name-matched Beans from {@link ListableBeanFactory BeanFactory}
+     *
+     * @param beanFactory {@link ListableBeanFactory BeanFactory}
+     * @param beanNames   the names of Bean
+     * @param beanType    the {@link Class type} of Bean
+     * @param <T>         the {@link Class type} of Bean
+     * @return the read-only and non-null {@link List} of Bean names
+     * @since 2.6.6
+     */
+    public static <T> List<T> getBeans(ListableBeanFactory beanFactory, String[] beanNames, Class<T> beanType) {
+
+        String[] allBeanNames = beanNamesForTypeIncludingAncestors(beanFactory, beanType);
+
+        List<T> beans = new ArrayList<T>(beanNames.length);
+
+        for (String beanName : beanNames) {
+            if (containsElement(allBeanNames, beanName)) {
+                beans.add(beanFactory.getBean(beanName, beanType));
+            }
+        }
+
+        return Collections.unmodifiableList(beans);
+    }
+
 }
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/BeanRegistrar.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/BeanRegistrar.java
index 671d63f..08a13ac 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/BeanRegistrar.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/BeanRegistrar.java
@@ -25,7 +25,7 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
  *
  * @since 2.5.7
  */
-public class BeanRegistrar {
+public abstract class BeanRegistrar {
 
     /**
      * Register Infrastructure Bean
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/ClassUtils.java
similarity index 53%
copy from dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
copy to dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/ClassUtils.java
index 1feb2bd..6bb1d81 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/ClassUtils.java
@@ -14,9 +14,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.alibaba.dubbo.config.spring.util;
 
-package com.alibaba.dubbo.config.spring.api;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
 
-public interface HelloService {
-    String sayHello(String name);
+/**
+ * {@link Class} 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/ClassUtils.java
+ *
+ * @since 2.6.6
+ */
+public abstract class ClassUtils {
+
+    public static <T> Class<T> resolveGenericType(Class<?> declaredClass) {
+        ParameterizedType parameterizedType = (ParameterizedType) declaredClass.getGenericSuperclass();
+        Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
+        return (Class<T>) actualTypeArguments[0];
+    }
 }
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/ObjectUtils.java
similarity index 68%
copy from dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
copy to dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/ObjectUtils.java
index 1feb2bd..abb981f 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/ObjectUtils.java
@@ -14,9 +14,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.alibaba.dubbo.config.spring.util;
 
-package com.alibaba.dubbo.config.spring.api;
+/**
+ * Object Utilities
+ *
+ * @since 2.6.6
+ */
+public abstract class ObjectUtils {
+
+    /**
+     * Convert from variable arguments to array
+     *
+     * @param values variable arguments
+     * @param <T>    The class
+     * @return array
+     */
+    public static <T> T[] of(T... values) {
+        return values;
+    }
 
-public interface HelloService {
-    String sayHello(String name);
 }
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/PropertySourcesUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/PropertySourcesUtils.java
new file mode 100644
index 0000000..06c7077
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/PropertySourcesUtils.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.config.spring.util;
+
+import org.springframework.core.env.AbstractEnvironment;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.EnumerablePropertySource;
+import org.springframework.core.env.MutablePropertySources;
+import org.springframework.core.env.PropertySource;
+import org.springframework.core.env.PropertySources;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Properties;
+
+
+/**
+ * {@link PropertySources} 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/PropertySourcesUtils.java
+ *
+ * @since 2.6.6
+ */
+public abstract class PropertySourcesUtils {
+
+    /**
+     * Get Sub {@link Properties}
+     *
+     * @param propertySources {@link PropertySource} Iterable
+     * @param prefix          the prefix of property name
+     * @return Map
+     * @see Properties
+     */
+    public static Map<String, Object> getSubProperties(Iterable<PropertySource<?>> propertySources, String prefix) {
+
+        // Non-Extension AbstractEnvironment
+        AbstractEnvironment environment = new AbstractEnvironment() {
+        };
+
+        MutablePropertySources mutablePropertySources = environment.getPropertySources();
+
+        for (PropertySource<?> source : propertySources) {
+            mutablePropertySources.addLast(source);
+        }
+
+        return getSubProperties(environment, prefix);
+
+    }
+
+    /**
+     * Get Sub {@link Properties}
+     *
+     * @param environment {@link ConfigurableEnvironment}
+     * @param prefix      the prefix of property name
+     * @return Map
+     * @see Properties
+     */
+    public static Map<String, Object> getSubProperties(ConfigurableEnvironment environment, String prefix) {
+
+        Map<String, Object> subProperties = new LinkedHashMap<String, Object>();
+
+        MutablePropertySources propertySources = environment.getPropertySources();
+
+        String normalizedPrefix = normalizePrefix(prefix);
+
+        for (PropertySource<?> source : propertySources) {
+            if (source instanceof EnumerablePropertySource) {
+                for (String name : ((EnumerablePropertySource<?>) source).getPropertyNames()) {
+                    if (!subProperties.containsKey(name) && name.startsWith(normalizedPrefix)) {
+                        String subName = name.substring(normalizedPrefix.length());
+                        if (!subProperties.containsKey(subName)) { // take first one
+                            Object value = source.getProperty(name);
+                            if (value instanceof String) {
+                                // Resolve placeholder
+                                value = environment.resolvePlaceholders((String) value);
+                            }
+                            subProperties.put(subName, value);
+                        }
+                    }
+                }
+            }
+        }
+
+        return Collections.unmodifiableMap(subProperties);
+
+    }
+
+    /**
+     * Normalize the prefix
+     *
+     * @param prefix the prefix
+     * @return the prefix
+     */
+    public static String normalizePrefix(String prefix) {
+        return prefix.endsWith(".") ? prefix : prefix + ".";
+    }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
index 1feb2bd..367ad9e 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
@@ -17,6 +17,13 @@
 
 package com.alibaba.dubbo.config.spring.api;
 
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.QueryParam;
+
+@Path("/hello-service")
 public interface HelloService {
-    String sayHello(String name);
+
+    @GET
+    String sayHello(@QueryParam("name") String name);
 }
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilderTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationBeanNameBuilderTest.java
similarity index 58%
copy from dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilderTest.java
copy to dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationBeanNameBuilderTest.java
index 84451bc..28c53cc 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilderTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/AnnotationBeanNameBuilderTest.java
@@ -21,25 +21,26 @@ import com.alibaba.dubbo.config.annotation.Service;
 import com.alibaba.dubbo.config.spring.api.DemoService;
 
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Test;
 import org.springframework.core.annotation.AnnotationUtils;
 import org.springframework.mock.env.MockEnvironment;
 import org.springframework.util.ReflectionUtils;
 
-import static com.alibaba.dubbo.config.spring.beans.factory.annotation.ServiceBeanNameBuilderTest.GROUP;
-import static com.alibaba.dubbo.config.spring.beans.factory.annotation.ServiceBeanNameBuilderTest.VERSION;
+import static com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationBeanNameBuilderTest.GROUP;
+import static com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationBeanNameBuilderTest.VERSION;
 
 /**
- * {@link ServiceBeanNameBuilder} Test
+ * {@link AnnotationBeanNameBuilder} Test
  *
- * @see ServiceBeanNameBuilder
- * @since 2.6.5
+ * @see AnnotationBeanNameBuilder
+ * @since 2.6.6
  */
 @Service(interfaceClass = DemoService.class, group = GROUP, version = VERSION,
         application = "application", module = "module", registry = {"1", "2", "3"})
-public class ServiceBeanNameBuilderTest {
+public class AnnotationBeanNameBuilderTest {
 
-    @Reference(interfaceClass = DemoService.class, group = "DUBBO", version = "1.0.0",
+    @Reference(interfaceClass = DemoService.class, group = "DUBBO", version = "${dubbo.version}",
             application = "application", module = "module", registry = {"1", "2", "3"})
     static final Class<?> INTERFACE_CLASS = DemoService.class;
 
@@ -47,29 +48,35 @@ public class ServiceBeanNameBuilderTest {
 
     static final String VERSION = "1.0.0";
 
-    static final String BEAN_NAME = "ServiceBean:com.alibaba.dubbo.config.spring.api.DemoService:1.0.0:DUBBO";
+    private MockEnvironment environment;
 
-    private MockEnvironment environment = new MockEnvironment();
-
-    @Test
-    public void testRequiredAttributes() {
-        ServiceBeanNameBuilder builder = ServiceBeanNameBuilder.create(INTERFACE_CLASS, environment);
-        Assert.assertEquals("ServiceBean:com.alibaba.dubbo.config.spring.api.DemoService", builder.build());
+    @Before
+    public void prepare() {
+        environment = new MockEnvironment();
+        environment.setProperty("dubbo.version", "1.0.0");
     }
 
     @Test
     public void testServiceAnnotation() {
-        Service service = AnnotationUtils.getAnnotation(ServiceBeanNameBuilderTest.class, Service.class);
-        ServiceBeanNameBuilder builder = ServiceBeanNameBuilder.create(service, INTERFACE_CLASS, environment);
-        Assert.assertEquals(BEAN_NAME,
+        Service service = AnnotationUtils.getAnnotation(AnnotationBeanNameBuilderTest.class, Service.class);
+        AnnotationBeanNameBuilder builder = AnnotationBeanNameBuilder.create(service, INTERFACE_CLASS);
+        Assert.assertEquals("providers:dubbo:com.alibaba.dubbo.config.spring.api.DemoService:1.0.0:DUBBO",
+                builder.build());
+
+        builder.environment(environment);
+        Assert.assertEquals("providers:dubbo:com.alibaba.dubbo.config.spring.api.DemoService:1.0.0:DUBBO",
                 builder.build());
     }
 
     @Test
     public void testReferenceAnnotation() {
-        Reference reference = AnnotationUtils.getAnnotation(ReflectionUtils.findField(ServiceBeanNameBuilderTest.class, "INTERFACE_CLASS"), Reference.class);
-        ServiceBeanNameBuilder builder = ServiceBeanNameBuilder.create(reference, INTERFACE_CLASS, environment);
-        Assert.assertEquals(BEAN_NAME,
+        Reference reference = AnnotationUtils.getAnnotation(ReflectionUtils.findField(AnnotationBeanNameBuilderTest.class, "INTERFACE_CLASS"), Reference.class);
+        AnnotationBeanNameBuilder builder = AnnotationBeanNameBuilder.create(reference, INTERFACE_CLASS);
+        Assert.assertEquals("consumers:dubbo:com.alibaba.dubbo.config.spring.api.DemoService:${dubbo.version}:DUBBO",
+                builder.build());
+
+        builder.environment(environment);
+        Assert.assertEquals("consumers:dubbo:com.alibaba.dubbo.config.spring.api.DemoService:1.0.0:DUBBO",
                 builder.build());
     }
 
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/DubboConfigBindingBeanPostProcessorTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/DubboConfigBindingBeanPostProcessorTest.java
index b98364b..818eade 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/DubboConfigBindingBeanPostProcessorTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/DubboConfigBindingBeanPostProcessorTest.java
@@ -17,51 +17,55 @@
 package com.alibaba.dubbo.config.spring.beans.factory.annotation;
 
 import com.alibaba.dubbo.config.ApplicationConfig;
+import com.alibaba.dubbo.config.spring.context.config.NamePropertyDefaultValueDubboConfigBeanCustomizer;
 import com.alibaba.dubbo.config.spring.context.properties.DefaultDubboConfigBinder;
-import com.alibaba.dubbo.config.spring.context.properties.DubboConfigBinder;
-
 import org.junit.Assert;
 import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.PropertySource;
-
-import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
 
 /**
  * {@link DubboConfigBindingBeanPostProcessor}
  */
-@PropertySource({"classpath:/META-INF/config.properties"})
-@Configuration
+@RunWith(SpringRunner.class)
+@ContextConfiguration(classes = {
+        DefaultDubboConfigBinder.class,
+        NamePropertyDefaultValueDubboConfigBeanCustomizer.class,
+        DubboConfigBindingBeanPostProcessorTest.class
+})
+@TestPropertySource(properties = {
+        "dubbo.application.id = dubbo-demo-application",
+        "dubbo.application.owner = mercyblitz",
+        "dubbo.application.organization = Apache",
+
+})
 public class DubboConfigBindingBeanPostProcessorTest {
 
-    @Bean("applicationBean")
+    @Bean("dubbo-demo-application")
     public ApplicationConfig applicationConfig() {
         return new ApplicationConfig();
     }
 
     @Bean
-    public DubboConfigBinder dubboConfigBinder() {
-        return new DefaultDubboConfigBinder();
+    public DubboConfigBindingBeanPostProcessor bindingBeanPostProcessor() {
+        return new DubboConfigBindingBeanPostProcessor("dubbo.application", "dubbo-demo-application");
     }
 
+    @Autowired
+    private ApplicationContext applicationContext;
+
     @Test
     public void test() {
 
-        final AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
-
-        applicationContext.register(getClass());
-
-        Class<?> processorClass = DubboConfigBindingBeanPostProcessor.class;
-
-        applicationContext.registerBeanDefinition("DubboConfigBindingBeanPostProcessor", rootBeanDefinition(processorClass).addConstructorArgValue("dubbo.application").addConstructorArgValue("applicationBean").getBeanDefinition());
-
-        applicationContext.refresh();
-
         ApplicationConfig applicationConfig = applicationContext.getBean(ApplicationConfig.class);
 
         Assert.assertEquals("dubbo-demo-application", applicationConfig.getName());
-
+        Assert.assertEquals("mercyblitz", applicationConfig.getOwner());
+        Assert.assertEquals("Apache", applicationConfig.getOrganization());
     }
 }
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
index a48a85e..dcb4127 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
@@ -124,7 +124,7 @@ public class ReferenceAnnotationBeanPostProcessorTest {
 
             InjectionMetadata.InjectedElement injectedElement = entry.getKey();
 
-            Assert.assertEquals("com.alibaba.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor$AnnotatedFieldElement",
+            Assert.assertEquals("com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor$AnnotatedFieldElement",
                     injectedElement.getClass().getName());
 
             ReferenceBean<?> referenceBean = entry.getValue();
@@ -152,7 +152,7 @@ public class ReferenceAnnotationBeanPostProcessorTest {
 
             InjectionMetadata.InjectedElement injectedElement = entry.getKey();
 
-            Assert.assertEquals("com.alibaba.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor$AnnotatedMethodElement",
+            Assert.assertEquals("com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor$AnnotatedMethodElement",
                     injectedElement.getClass().getName());
 
             ReferenceBean<?> referenceBean = entry.getValue();
@@ -229,7 +229,7 @@ public class ReferenceAnnotationBeanPostProcessorTest {
             return demoService;
         }
 
-        @Reference(version = "2.5.7", url = "dubbo://127.0.0.1:12345")
+        @Reference(version = "2.5.7", url = "dubbo://127.0.0.1:12345", protocol = "dubbo")
         public void setDemoService(DemoService demoService) {
             this.demoService = demoService;
         }
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilderTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilderTest.java
new file mode 100644
index 0000000..54b1b97
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilderTest.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.config.spring.beans.factory.annotation;
+
+import com.alibaba.dubbo.config.annotation.Reference;
+import com.alibaba.dubbo.config.spring.ReferenceBean;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
+import static org.springframework.util.ReflectionUtils.findField;
+
+/**
+ * {@link ReferenceBeanBuilder} Test
+ *
+ * @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
+ * @see ReferenceBeanBuilder
+ * @see Reference
+ * @since 2.6.4
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = ReferenceBeanBuilderTest.class)
+public class ReferenceBeanBuilderTest {
+
+    @Reference(
+            interfaceClass = CharSequence.class,
+            interfaceName = "java.lang.CharSequence",
+            version = "1.0.0", group = "TEST_GROUP", url = "dubbo://localhost:12345",
+            client = "client", generic = true, injvm = true,
+            check = false, init = false, lazy = true,
+            stubevent = true, reconnect = "reconnect", sticky = true,
+            proxy = "javassist", stub = "java.lang.CharSequence", cluster = "failover",
+            connections = 3, callbacks = 1, onconnect = "onconnect", ondisconnect = "ondisconnect",
+            owner = "owner", layer = "layer", retries = 1,
+            loadbalance = "random", async = true, actives = 3,
+            sent = true, mock = "mock", validation = "validation",
+            timeout = 3, cache = "cache", filter = {"echo", "generic", "accesslog"},
+            listener = {"deprecated"}, parameters = {"n1=v1  ", "n2 = v2 ", "  n3 =   v3  "},
+            application = "application",
+            module = "module", consumer = "consumer", monitor = "monitor", registry = {"registry"}
+    )
+    private static final Object TEST_FIELD = new Object();
+
+    @Autowired
+    private ApplicationContext context;
+
+    @Test
+    public void testBuild() throws Exception {
+        Reference reference = findAnnotation(findField(getClass(), "TEST_FIELD"), Reference.class);
+        ReferenceBeanBuilder beanBuilder = ReferenceBeanBuilder.create(reference, context.getClassLoader(), context);
+        beanBuilder.interfaceClass(CharSequence.class);
+        ReferenceBean referenceBean = beanBuilder.build();
+        Assert.assertEquals(CharSequence.class, referenceBean.getInterfaceClass());
+        Assert.assertEquals("1.0.0", referenceBean.getVersion());
+        Assert.assertEquals("TEST_GROUP", referenceBean.getGroup());
+        Assert.assertEquals("dubbo://localhost:12345", referenceBean.getUrl());
+        Assert.assertEquals("client", referenceBean.getClient());
+        Assert.assertEquals(true, referenceBean.isGeneric());
+        Assert.assertEquals(true, referenceBean.isInjvm());
+        Assert.assertEquals(false, referenceBean.isCheck());
+        Assert.assertEquals(null, referenceBean.isInit());
+        Assert.assertEquals(true, referenceBean.getLazy());
+        Assert.assertEquals(true, referenceBean.getStubevent());
+        Assert.assertEquals("reconnect", referenceBean.getReconnect());
+        Assert.assertEquals(true, referenceBean.getSticky());
+        Assert.assertEquals("javassist", referenceBean.getProxy());
+        Assert.assertEquals("java.lang.CharSequence", referenceBean.getStub());
+        Assert.assertEquals("failover", referenceBean.getCluster());
+        Assert.assertEquals(Integer.valueOf(3), referenceBean.getConnections());
+        Assert.assertEquals(Integer.valueOf(1), referenceBean.getCallbacks());
+        Assert.assertEquals("onconnect", referenceBean.getOnconnect());
+        Assert.assertEquals("ondisconnect", referenceBean.getOndisconnect());
+        Assert.assertEquals("owner", referenceBean.getOwner());
+        Assert.assertEquals("layer", referenceBean.getLayer());
+        Assert.assertEquals(Integer.valueOf(1), referenceBean.getRetries());
+        Assert.assertEquals("random", referenceBean.getLoadbalance());
+        Assert.assertEquals(true, referenceBean.isAsync());
+        Assert.assertEquals(Integer.valueOf(3), referenceBean.getActives());
+        Assert.assertEquals(true, referenceBean.getSent());
+        Assert.assertEquals("mock", referenceBean.getMock());
+        Assert.assertEquals("validation", referenceBean.getValidation());
+        Assert.assertEquals(Integer.valueOf(3), referenceBean.getTimeout());
+        Assert.assertEquals("cache", referenceBean.getCache());
+        Assert.assertEquals("echo,generic,accesslog", referenceBean.getFilter());
+        Assert.assertEquals("deprecated", referenceBean.getListener());
+
+        // parameters
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put("n1", "v1");
+        parameters.put("n2", "v2");
+        parameters.put("n3", "v3");
+        Assert.assertEquals(parameters, referenceBean.getParameters());
+
+        // Asserts Null fields
+        Assert.assertNull(referenceBean.getApplication());
+        Assert.assertNull(referenceBean.getModule());
+        Assert.assertNull(referenceBean.getConsumer());
+        Assert.assertNull(referenceBean.getMonitor());
+        Assert.assertEquals(Collections.emptyList(), referenceBean.getRegistries());
+    }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilderTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilderTest.java
index 84451bc..91b4b70 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilderTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilderTest.java
@@ -37,6 +37,7 @@ import static com.alibaba.dubbo.config.spring.beans.factory.annotation.ServiceBe
  */
 @Service(interfaceClass = DemoService.class, group = GROUP, version = VERSION,
         application = "application", module = "module", registry = {"1", "2", "3"})
+@Deprecated
 public class ServiceBeanNameBuilderTest {
 
     @Reference(interfaceClass = DemoService.class, group = "DUBBO", version = "1.0.0",
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/multiple/EmbeddedZooKeeper.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/multiple/EmbeddedZooKeeper.java
new file mode 100644
index 0000000..05c08e7
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/multiple/EmbeddedZooKeeper.java
@@ -0,0 +1,252 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.config.spring.beans.factory.annotation.multiple;
+
+
+import org.apache.zookeeper.server.ServerConfig;
+import org.apache.zookeeper.server.ZooKeeperServerMain;
+import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.SmartLifecycle;
+import org.springframework.util.ErrorHandler;
+import org.springframework.util.SocketUtils;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.util.Properties;
+import java.util.UUID;
+
+/**
+ * from: https://github.com/spring-projects/spring-xd/blob/v1.3.1.RELEASE/spring-xd-dirt/src/main/java/org/springframework/xd/dirt/zookeeper/ZooKeeperUtils.java
+ * <p>
+ * Helper class to start an embedded instance of standalone (non clustered) ZooKeeper.
+ * <p>
+ * NOTE: at least an external standalone server (if not an ensemble) are recommended, even for
+ * org.springframework.xd.dirt.server.singlenode.SingleNodeApplication
+ *
+ * @author Patrick Peralta
+ * @author Mark Fisher
+ * @author David Turanski
+ */
+public class EmbeddedZooKeeper implements SmartLifecycle {
+
+    /**
+     * Logger.
+     */
+    private static final Logger logger = LoggerFactory.getLogger(EmbeddedZooKeeper.class);
+
+    /**
+     * ZooKeeper client port. This will be determined dynamically upon startup.
+     */
+    private final int clientPort;
+
+    /**
+     * Whether to auto-start. Default is true.
+     */
+    private boolean autoStartup = true;
+
+    /**
+     * Lifecycle phase. Default is 0.
+     */
+    private int phase = 0;
+
+    /**
+     * Thread for running the ZooKeeper server.
+     */
+    private volatile Thread zkServerThread;
+
+    /**
+     * ZooKeeper server.
+     */
+    private volatile ZooKeeperServerMain zkServer;
+
+    /**
+     * {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread.
+     */
+    private ErrorHandler errorHandler;
+
+    private boolean daemon = true;
+
+    /**
+     * Construct an EmbeddedZooKeeper with a random port.
+     */
+    public EmbeddedZooKeeper() {
+        clientPort = SocketUtils.findAvailableTcpPort();
+    }
+
+    /**
+     * Construct an EmbeddedZooKeeper with the provided port.
+     *
+     * @param clientPort port for ZooKeeper server to bind to
+     */
+    public EmbeddedZooKeeper(int clientPort, boolean daemon) {
+        this.clientPort = clientPort;
+        this.daemon = daemon;
+    }
+
+    /**
+     * Returns the port that clients should use to connect to this embedded server.
+     *
+     * @return dynamically determined client port
+     */
+    public int getClientPort() {
+        return this.clientPort;
+    }
+
+    /**
+     * Specify whether to start automatically. Default is true.
+     *
+     * @param autoStartup whether to start automatically
+     */
+    public void setAutoStartup(boolean autoStartup) {
+        this.autoStartup = autoStartup;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isAutoStartup() {
+        return this.autoStartup;
+    }
+
+    /**
+     * Specify the lifecycle phase for the embedded server.
+     *
+     * @param phase the lifecycle phase
+     */
+    public void setPhase(int phase) {
+        this.phase = phase;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int getPhase() {
+        return this.phase;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isRunning() {
+        return (zkServerThread != null);
+    }
+
+    /**
+     * Start the ZooKeeper server in a background thread.
+     * <p>
+     * Register an error handler via {@link #setErrorHandler} in order to handle
+     * any exceptions thrown during startup or execution.
+     */
+    @Override
+    public synchronized void start() {
+        if (zkServerThread == null) {
+            zkServerThread = new Thread(new ServerRunnable(), "ZooKeeper Server Starter");
+            zkServerThread.setDaemon(daemon);
+            zkServerThread.start();
+        }
+    }
+
+    /**
+     * Shutdown the ZooKeeper server.
+     */
+    @Override
+    public synchronized void stop() {
+        if (zkServerThread != null) {
+            // The shutdown method is protected...thus this hack to invoke it.
+            // This will log an exception on shutdown; see
+            // https://issues.apache.org/jira/browse/ZOOKEEPER-1873 for details.
+            try {
+                Method shutdown = ZooKeeperServerMain.class.getDeclaredMethod("shutdown");
+                shutdown.setAccessible(true);
+                shutdown.invoke(zkServer);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+
+            // It is expected that the thread will exit after
+            // the server is shutdown; this will block until
+            // the shutdown is complete.
+            try {
+                zkServerThread.join(5000);
+                zkServerThread = null;
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                logger.warn("Interrupted while waiting for embedded ZooKeeper to exit");
+                // abandoning zk thread
+                zkServerThread = null;
+            }
+        }
+    }
+
+    /**
+     * Stop the server if running and invoke the callback when complete.
+     */
+    @Override
+    public void stop(Runnable callback) {
+        stop();
+        callback.run();
+    }
+
+    /**
+     * Provide an {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread. If none
+     * is provided, only error-level logging will occur.
+     *
+     * @param errorHandler the {@link ErrorHandler} to be invoked
+     */
+    public void setErrorHandler(ErrorHandler errorHandler) {
+        this.errorHandler = errorHandler;
+    }
+
+    /**
+     * Runnable implementation that starts the ZooKeeper server.
+     */
+    private class ServerRunnable implements Runnable {
+
+        @Override
+        public void run() {
+            try {
+                Properties properties = new Properties();
+                File file = new File(System.getProperty("java.io.tmpdir")
+                        + File.separator + UUID.randomUUID());
+                file.deleteOnExit();
+                properties.setProperty("dataDir", file.getAbsolutePath());
+                properties.setProperty("clientPort", String.valueOf(clientPort));
+
+                QuorumPeerConfig quorumPeerConfig = new QuorumPeerConfig();
+                quorumPeerConfig.parseProperties(properties);
+
+                zkServer = new ZooKeeperServerMain();
+                ServerConfig configuration = new ServerConfig();
+                configuration.readFrom(quorumPeerConfig);
+
+                zkServer.runFromConfig(configuration);
+            } catch (Exception e) {
+                if (errorHandler != null) {
+                    errorHandler.handleError(e);
+                } else {
+                    logger.error("Exception running embedded ZooKeeper", e);
+                }
+            }
+        }
+    }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/multiple/consumer/MultipleProtocolsServiceConsumer.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/multiple/consumer/MultipleProtocolsServiceConsumer.java
new file mode 100644
index 0000000..5166db8
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/multiple/consumer/MultipleProtocolsServiceConsumer.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.config.spring.beans.factory.annotation.multiple.consumer;
+
+import com.alibaba.dubbo.config.annotation.Reference;
+import com.alibaba.dubbo.config.spring.api.HelloService;
+import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
+
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+
+/**
+ * Multiple Protocols Test
+ */
+
+public class MultipleProtocolsServiceConsumer {
+
+    @EnableDubbo
+    @PropertySource({
+            "classpath:/META-INF/multiple-protocols-consumer.properties",
+            "classpath:/META-INF/dubbo-common.properties"
+    })
+    @Configuration
+    static class ConsumerConfiguration {
+
+        @Reference(version = "${hello.service.version}", protocol = "dubbo")
+        private HelloService dubboHelloService;
+
+        @Reference(version = "${hello.service.version}", protocol = "rest")
+        private HelloService restHelloService;
+
+//        @Bean
+//        public ReferenceBean<HelloService> restReferenceBean(@Value("${hello.service.version}") String version) {
+//            ReferenceBean<HelloService> referenceBean = new ReferenceBean<HelloService>();
+//            referenceBean.setVersion(version);
+//            referenceBean.setProtocol("rest");
+//            referenceBean.setInterface(HelloService.class);
+//            return referenceBean;
+//        }
+
+    }
+
+//    @ImportResource("classpath:/META-INF/spring/dubbo-rest-consumer.xml")
+//    @Configuration
+//    static class ConsumerXMLConfiguration {
+//    }
+
+
+    public static void main(String[] args) {
+
+        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
+        context.register(ConsumerConfiguration.class);
+        context.refresh();
+
+        ConsumerConfiguration configuration = context.getBean(ConsumerConfiguration.class);
+        System.out.println(configuration.dubboHelloService.sayHello("mercyblitz"));
+        System.out.println(configuration.restHelloService.sayHello("mercyblitz"));
+
+        context.close();
+    }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/multiple/provider/DefaultHelloService.java
similarity index 60%
copy from dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
copy to dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/multiple/provider/DefaultHelloService.java
index 1feb2bd..43a7ced 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/multiple/provider/DefaultHelloService.java
@@ -14,9 +14,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.alibaba.dubbo.config.spring.beans.factory.annotation.multiple.provider;
 
-package com.alibaba.dubbo.config.spring.api;
+import com.alibaba.dubbo.config.annotation.Service;
+import com.alibaba.dubbo.config.spring.api.HelloService;
+import com.alibaba.dubbo.rpc.RpcContext;
 
-public interface HelloService {
-    String sayHello(String name);
+@Service(version = "${hello.service.version}", protocol = {"dubbo", "rest"})
+public class DefaultHelloService implements HelloService {
+
+    @Override
+    public String sayHello(String name) {
+        return String.format("[%s] Hello , %s", RpcContext.getContext().getUrl(), name);
+    }
 }
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingsRegistrarTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/multiple/provider/MultipleProtocolsServiceProvider.java
similarity index 51%
copy from dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingsRegistrarTest.java
copy to dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/multiple/provider/MultipleProtocolsServiceProvider.java
index a73dbf2..e55d70a 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingsRegistrarTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/multiple/provider/MultipleProtocolsServiceProvider.java
@@ -14,47 +14,37 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.alibaba.dubbo.config.spring.context.annotation;
+package com.alibaba.dubbo.config.spring.beans.factory.annotation.multiple.provider;
 
-import com.alibaba.dubbo.config.ApplicationConfig;
+import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
 
-import org.junit.Assert;
-import org.junit.Test;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 import org.springframework.context.annotation.PropertySource;
 
+import java.io.IOException;
+
 /**
- * {@link DubboConfigBindingsRegistrar} Test
- *
- * @since DubboConfigBindingsRegistrar
+ * Multiple Protocols Service Provider
  */
-public class DubboConfigBindingsRegistrarTest {
+@EnableDubbo
+@PropertySource({
+        "classpath:/META-INF/multiple-protocols-provider.properties",
+        "classpath:/META-INF/dubbo-common.properties"
+})
+public class MultipleProtocolsServiceProvider {
 
-    @Test
-    public void test() {
+    public static void main(String[] args) throws IOException {
+//        EmbeddedZooKeeper embeddedZooKeeper = new EmbeddedZooKeeper(2181, false);
+//        embeddedZooKeeper.start();
 
         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
-
-        context.register(TestConfig.class);
-
+        context.register(MultipleProtocolsServiceProvider.class);
         context.refresh();
 
-        ApplicationConfig applicationConfig = context.getBean("applicationBean", ApplicationConfig.class);
-
-        Assert.assertEquals("dubbo-demo-application", applicationConfig.getName());
-
-        Assert.assertEquals(2, context.getBeansOfType(ApplicationConfig.class).size());
+        System.out.println("Enter any key to close the application");
+        System.in.read();
 
+        context.close();
+//        embeddedZooKeeper.stop();
     }
-
-
-    @EnableDubboConfigBindings({
-            @EnableDubboConfigBinding(prefix = "${application.prefix}", type = ApplicationConfig.class),
-            @EnableDubboConfigBinding(prefix = "dubbo.applications.applicationBean", type = ApplicationConfig.class)
-    })
-    @PropertySource("META-INF/config.properties")
-    private static class TestConfig {
-
-    }
-
 }
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboComponentScanRegistrarTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboComponentScanRegistrarTest.java
index 54d6c97..20a1504 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboComponentScanRegistrarTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboComponentScanRegistrarTest.java
@@ -111,5 +111,31 @@ public class DubboComponentScanRegistrarTest {
 
     }
 
+    @Test(expected = UnsupportedOperationException.class)
+    public void testOnException() {
+
+        AnnotationConfigApplicationContext providerContext = new AnnotationConfigApplicationContext();
+
+        providerContext.register(ProviderConfiguration.class);
+
+        providerContext.refresh();
+
+        AnnotationConfigApplicationContext consumerContext = new AnnotationConfigApplicationContext();
+
+        consumerContext.register(ConsumerConfiguration.class);
+
+        consumerContext.refresh();
+
+        ConsumerConfiguration.Child child = consumerContext.getBean(ConsumerConfiguration.Child.class);
+
+        // From Child
+        DemoService demoService = child.getDemoServiceFromChild();
+
+        demoService.getBox();
+
+        providerContext.close();
+        consumerContext.close();
+    }
+
 
 }
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingRegistrarTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingRegistrarTest.java
index 853df84..30fc54a 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingRegistrarTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingRegistrarTest.java
@@ -23,6 +23,11 @@ import org.junit.Test;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 import org.springframework.context.annotation.PropertySource;
 
+import java.util.Set;
+import java.util.TreeSet;
+
+import static java.util.Arrays.asList;
+
 /**
  * {@link DubboConfigBindingRegistrar}
  *
@@ -55,9 +60,14 @@ public class DubboConfigBindingRegistrarTest {
 
         context.refresh();
 
-        ApplicationConfig applicationConfig = context.getBean("applicationBean", ApplicationConfig.class);
+        Set<String> expectedBeanNames = new TreeSet<String>(asList("applicationBean1", "applicationBean2", "applicationBean3"));
+        Set<String> actualBeanNames = new TreeSet<String>(asList(context.getBeanNamesForType(ApplicationConfig.class)));
 
-        Assert.assertEquals("dubbo-demo-application", applicationConfig.getName());
+        Assert.assertEquals(expectedBeanNames, actualBeanNames);
+
+        ApplicationConfig applicationConfig = context.getBean("applicationBean1", ApplicationConfig.class);
+
+        Assert.assertEquals("dubbo-demo-application1", applicationConfig.getName());
 
         applicationConfig = context.getBean("applicationBean2", ApplicationConfig.class);
 
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingsRegistrarTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingsRegistrarTest.java
index a73dbf2..b871983 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingsRegistrarTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingsRegistrarTest.java
@@ -50,7 +50,7 @@ public class DubboConfigBindingsRegistrarTest {
 
     @EnableDubboConfigBindings({
             @EnableDubboConfigBinding(prefix = "${application.prefix}", type = ApplicationConfig.class),
-            @EnableDubboConfigBinding(prefix = "dubbo.applications.applicationBean", type = ApplicationConfig.class)
+            @EnableDubboConfigBinding(prefix = "dubbo.applications.applicationBean1", type = ApplicationConfig.class)
     })
     @PropertySource("META-INF/config.properties")
     private static class TestConfig {
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigConfigurationTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigConfigurationTest.java
index ff21bcd..5a4222e 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigConfigurationTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigConfigurationTest.java
@@ -84,8 +84,8 @@ public class DubboConfigConfigurationTest {
         context.refresh();
 
         // application
-        ApplicationConfig applicationConfig = context.getBean("applicationBean", ApplicationConfig.class);
-        Assert.assertEquals("dubbo-demo-application", applicationConfig.getName());
+        ApplicationConfig applicationConfig = context.getBean("applicationBean1", ApplicationConfig.class);
+        Assert.assertEquals("dubbo-demo-application1", applicationConfig.getName());
 
         ApplicationConfig applicationBean2 = context.getBean("applicationBean2", ApplicationConfig.class);
         Assert.assertEquals("dubbo-demo-application2", applicationBean2.getName());
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java
index d5c41b0..15b462e 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java
@@ -23,12 +23,18 @@ import com.alibaba.dubbo.config.MonitorConfig;
 import com.alibaba.dubbo.config.ProtocolConfig;
 import com.alibaba.dubbo.config.ProviderConfig;
 import com.alibaba.dubbo.config.RegistryConfig;
-
+import com.alibaba.dubbo.config.spring.util.ObjectUtils;
 import org.junit.Assert;
 import org.junit.Test;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 import org.springframework.context.annotation.PropertySource;
 
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import static java.util.Arrays.asList;
+
 /**
  * {@link EnableDubboConfig} Test
  *
@@ -47,6 +53,8 @@ public class EnableDubboConfigTest {
         ApplicationConfig applicationConfig = context.getBean("applicationBean", ApplicationConfig.class);
         Assert.assertEquals("dubbo-demo-application", applicationConfig.getName());
 
+        Assert.assertArrayEquals(ObjectUtils.of("applicationBean"), context.getBeanNamesForType(ApplicationConfig.class));
+
         // module
         ModuleConfig moduleConfig = context.getBean("moduleBean", ModuleConfig.class);
         Assert.assertEquals("dubbo-demo-module", moduleConfig.getName());
@@ -82,25 +90,42 @@ public class EnableDubboConfigTest {
         context.register(TestMultipleConfig.class);
         context.refresh();
 
+        Set<String> expectedBeanNames = new TreeSet<String>(asList("applicationBean", "applicationBean1", "applicationBean2", "applicationBean3"));
+        Set<String> actualBeanNames = new TreeSet<String>(asList(context.getBeanNamesForType(ApplicationConfig.class)));
+
+        Assert.assertEquals(expectedBeanNames, actualBeanNames);
+
         // application
         ApplicationConfig applicationConfig = context.getBean("applicationBean", ApplicationConfig.class);
         Assert.assertEquals("dubbo-demo-application", applicationConfig.getName());
 
+        applicationConfig = context.getBean("applicationBean1", ApplicationConfig.class);
+        Assert.assertEquals("dubbo-demo-application1", applicationConfig.getName());
+
         ApplicationConfig applicationBean2 = context.getBean("applicationBean2", ApplicationConfig.class);
         Assert.assertEquals("dubbo-demo-application2", applicationBean2.getName());
 
         ApplicationConfig applicationBean3 = context.getBean("applicationBean3", ApplicationConfig.class);
         Assert.assertEquals("dubbo-demo-application3", applicationBean3.getName());
 
+
+        Map<String, ProtocolConfig> protocolConfigs = context.getBeansOfType(ProtocolConfig.class);
+
+        for (Map.Entry<String, ProtocolConfig> entry : protocolConfigs.entrySet()) {
+            String beanName = entry.getKey();
+            ProtocolConfig protocol = entry.getValue();
+            Assert.assertEquals(beanName, protocol.getName());
+        }
+
     }
 
-    @EnableDubboConfig(multiple = true)
+    @EnableDubboConfig
     @PropertySource("META-INF/config.properties")
     private static class TestMultipleConfig {
 
     }
 
-    @EnableDubboConfig
+    @EnableDubboConfig(multiple = false)
     @PropertySource("META-INF/config.properties")
     private static class TestConfig {
 
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboTest.java
index e419632..29d8a3c 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/EnableDubboTest.java
@@ -24,12 +24,14 @@ import com.alibaba.dubbo.config.spring.context.annotation.provider.DemoServiceIm
 
 import org.junit.Assert;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.springframework.aop.support.AopUtils;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Primary;
-import org.springframework.context.annotation.PropertySource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.*;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 import org.springframework.transaction.PlatformTransactionManager;
 import org.springframework.transaction.TransactionDefinition;
 import org.springframework.transaction.TransactionException;
@@ -44,17 +46,21 @@ import static org.springframework.core.annotation.AnnotationUtils.findAnnotation
  *
  * @since 2.5.8
  */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = {EnableDubboTest.class})
+@TestPropertySource(locations = "classpath:/META-INF/dubbb-provider.properties",
+        properties = "demo.service.version = 2.5.7")
+@EnableDubbo(scanBasePackages = "com.alibaba.dubbo.config.spring.context.annotation.provider")
+@ComponentScan(basePackages = "com.alibaba.dubbo.config.spring.context.annotation.provider")
+@EnableTransactionManagement
 public class EnableDubboTest {
 
+    @Autowired
+    private ApplicationContext providerContext;
+
     @Test
     public void test() {
 
-        AnnotationConfigApplicationContext providerContext = new AnnotationConfigApplicationContext();
-
-        providerContext.register(TestProviderConfiguration.class);
-
-        providerContext.refresh();
-
         DemoService demoService = providerContext.getBean(DemoService.class);
 
         String value = demoService.sayName("Mercy");
@@ -69,11 +75,7 @@ public class EnableDubboTest {
         // Test @Transactional is present or not
         Assert.assertNotNull(findAnnotation(beanClass, Transactional.class));
 
-        AnnotationConfigApplicationContext consumerContext = new AnnotationConfigApplicationContext();
-
-        consumerContext.register(TestConsumerConfiguration.class);
-
-        consumerContext.refresh();
+        AnnotationConfigApplicationContext consumerContext = new AnnotationConfigApplicationContext(TestConsumerConfiguration.class);
 
         TestConsumerConfiguration consumerConfiguration = consumerContext.getBean(TestConsumerConfiguration.class);
 
@@ -128,10 +130,6 @@ public class EnableDubboTest {
         // Test multiple binding
         Assert.assertEquals("N/A", registryConfig.getAddress());
 
-        providerContext.close();
-        consumerContext.close();
-
-
     }
 
     @EnableDubbo(scanBasePackages = "com.alibaba.dubbo.config.spring.context.annotation.provider")
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/provider/DemoServiceImpl.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/provider/DemoServiceImpl.java
index 2641fae..84c451a 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/provider/DemoServiceImpl.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/provider/DemoServiceImpl.java
@@ -29,7 +29,7 @@ import org.springframework.transaction.annotation.Transactional;
  * @since 2.5.8
  */
 @com.alibaba.dubbo.config.annotation.Service(
-        version = "2.5.7",
+        version = "${demo.service.version}",
         application = "${demo.service.application}",
         protocol = "${demo.service.protocol}",
         registry = "${demo.service.registry}"
@@ -45,11 +45,6 @@ public class DemoServiceImpl implements DemoService {
 
     @Override
     public Box getBox() {
-        return new Box() {
-            @Override
-            public String getName() {
-                return "MyBox";
-            }
-        };
+        throw new UnsupportedOperationException("For Purposes!");
     }
 }
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtilsTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtilsTest.java
new file mode 100644
index 0000000..c54fa9f
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtilsTest.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.config.spring.util;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.context.annotation.AnnotationConfigUtils;
+import org.springframework.util.ObjectUtils;
+
+/**
+ * {@link AnnotatedBeanDefinitionRegistryUtils} Test
+ *
+ * @see AnnotatedBeanDefinitionRegistryUtils
+ * @since 2.6.6
+ */
+public class AnnotatedBeanDefinitionRegistryUtilsTest {
+
+    private DefaultListableBeanFactory registry = null;
+
+    @Before
+    public void init() {
+        registry = new DefaultListableBeanFactory();
+        AnnotationConfigUtils.registerAnnotationConfigProcessors(registry);
+    }
+
+    @Test
+    public void testRegisterBeans() {
+
+        AnnotatedBeanDefinitionRegistryUtils.registerBeans(registry, this.getClass());
+
+        String[] beanNames = registry.getBeanNamesForType(this.getClass());
+
+        Assert.assertEquals(1, beanNames.length);
+
+        beanNames = registry.getBeanNamesForType(AnnotatedBeanDefinitionRegistryUtils.class);
+
+        Assert.assertTrue(ObjectUtils.isEmpty(beanNames));
+
+        AnnotatedBeanDefinitionRegistryUtils.registerBeans(registry);
+
+    }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/util/PropertySourcesUtilsTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/util/PropertySourcesUtilsTest.java
new file mode 100644
index 0000000..4a17ac1
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/util/PropertySourcesUtilsTest.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.config.spring.util;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.core.env.MapPropertySource;
+import org.springframework.core.env.MutablePropertySources;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * {@link PropertySourcesUtils} Test
+ *
+ * @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
+ * @see PropertySourcesUtils
+ * @since 2.6.6
+ */
+public class PropertySourcesUtilsTest {
+
+    @Test
+    public void testGetSubProperties() {
+
+        MutablePropertySources propertySources = new MutablePropertySources();
+
+        Map<String, Object> source = new HashMap<String, Object>();
+        Map<String, Object> source2 = new HashMap<String, Object>();
+
+        MapPropertySource propertySource = new MapPropertySource("propertySource", source);
+        MapPropertySource propertySource2 = new MapPropertySource("propertySource2", source2);
+
+        propertySources.addLast(propertySource);
+        propertySources.addLast(propertySource2);
+
+        Map<String, Object> result = PropertySourcesUtils.getSubProperties(propertySources, "user");
+
+        Assert.assertEquals(Collections.emptyMap(), result);
+
+        source.put("age", "31");
+        source.put("user.name", "Mercy");
+        source.put("user.age", "${age}");
+
+        source2.put("user.name", "mercyblitz");
+        source2.put("user.age", "32");
+
+        Map<String, Object> expected = new HashMap<String, Object>();
+        expected.put("name", "Mercy");
+        expected.put("age", "31");
+
+        result = PropertySourcesUtils.getSubProperties(propertySources, "user");
+
+        Assert.assertEquals(expected, result);
+
+        result = PropertySourcesUtils.getSubProperties(propertySources, "");
+
+        Assert.assertEquals(Collections.emptyMap(), result);
+
+        result = PropertySourcesUtils.getSubProperties(propertySources, "no-exists");
+
+        Assert.assertEquals(Collections.emptyMap(), result);
+
+    }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/config.properties b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/config.properties
index 6e728cc..1063fe6 100644
--- a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/config.properties
+++ b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/config.properties
@@ -14,9 +14,13 @@ dubbo.module.name = dubbo-demo-module
 dubbo.registry.address = zookeeper://192.168.99.100:32770
 
 ## protocol
+dubbo.protocol.id = dubbo
 dubbo.protocol.name = dubbo
 dubbo.protocol.port = 20880
 
+dubbo.protocols.rest.port=8080
+dubbo.protocols.thrift.port=9090
+
 ## monitor
 dubbo.monitor.address = zookeeper://127.0.0.1:32770
 
@@ -27,6 +31,6 @@ dubbo.provider.host = 127.0.0.1
 dubbo.consumer.client = netty
 
 # multiple Bean definition
-dubbo.applications.applicationBean.name = dubbo-demo-application
+dubbo.applications.applicationBean1.name = dubbo-demo-application1
 dubbo.applications.applicationBean2.name = dubbo-demo-application2
 dubbo.applications.applicationBean3.name = dubbo-demo-application3
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/dubbo-common.properties b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/dubbo-common.properties
new file mode 100644
index 0000000..36146a1
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/dubbo-common.properties
@@ -0,0 +1,2 @@
+dubbo.registry.address=zookeeper://127.0.0.1:2181
+hello.service.version=1.0.0
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/multiple-protocols-consumer.properties b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/multiple-protocols-consumer.properties
new file mode 100644
index 0000000..abbe51c
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/multiple-protocols-consumer.properties
@@ -0,0 +1 @@
+dubbo.application.id=provider
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/multiple-protocols-provider.properties b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/multiple-protocols-provider.properties
new file mode 100644
index 0000000..9879049
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/multiple-protocols-provider.properties
@@ -0,0 +1,6 @@
+dubbo.application.id=provider
+dubbo.protocols.dubbo.name=dubbo
+dubbo.protocols.dubbo.port=12345
+dubbo.protocols.rest.name=rest
+dubbo.protocols.rest.port=9090
+dubbo.protocols.rest.server=netty
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/spring/dubbo-rest-consumer.xml b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/spring/dubbo-rest-consumer.xml
new file mode 100644
index 0000000..c7db5ff
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/spring/dubbo-rest-consumer.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
+       xmlns="http://www.springframework.org/schema/beans"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
+        http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
+
+    <dubbo:application name="dubbo-rest-consumer"/>
+
+    <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
+
+    <dubbo:reference id="restReferenceBean" interface="com.alibaba.dubbo.config.spring.api.HelloService"
+                     version="1.0.0"
+                     protocol="rest"/>
+
+</beans>
\ No newline at end of file
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/com/alibaba/dubbo/registry/support/DubboRegistration.java b/dubbo-registry/dubbo-registry-api/src/main/java/com/alibaba/dubbo/registry/support/DubboRegistration.java
new file mode 100644
index 0000000..50deb0a
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/com/alibaba/dubbo/registry/support/DubboRegistration.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.registry.support;
+
+import java.util.Map;
+
+/**
+ * Dubbo Registration
+ *
+ * @since 2.6.6
+ */
+class DubboRegistration implements Registration {
+
+    private String serviceName;
+
+    private String ip;
+
+    private int port;
+
+    private Map<String, String> metadata;
+
+    @Override
+    public String getServiceName() {
+        return serviceName;
+    }
+
+    public void setServiceName(String serviceName) {
+        this.serviceName = serviceName;
+    }
+
+    @Override
+    public String getIp() {
+        return ip;
+    }
+
+    public void setIp(String ip) {
+        this.ip = ip;
+    }
+
+    @Override
+    public int getPort() {
+        return port;
+    }
+
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    @Override
+    public Map<String, String> getMetadata() {
+        return metadata;
+    }
+
+    public void setMetadata(Map<String, String> metadata) {
+        this.metadata = metadata;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        DubboRegistration that = (DubboRegistration) o;
+
+        if (port != that.port) return false;
+        if (serviceName != null ? !serviceName.equals(that.serviceName) : that.serviceName != null) return false;
+        if (ip != null ? !ip.equals(that.ip) : that.ip != null) return false;
+        return metadata != null ? metadata.equals(that.metadata) : that.metadata == null;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = serviceName != null ? serviceName.hashCode() : 0;
+        result = 31 * result + (ip != null ? ip.hashCode() : 0);
+        result = 31 * result + port;
+        result = 31 * result + (metadata != null ? metadata.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java b/dubbo-registry/dubbo-registry-api/src/main/java/com/alibaba/dubbo/registry/support/Registration.java
similarity index 60%
copy from dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
copy to dubbo-registry/dubbo-registry-api/src/main/java/com/alibaba/dubbo/registry/support/Registration.java
index 1feb2bd..143cc9f 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/com/alibaba/dubbo/registry/support/Registration.java
@@ -14,9 +14,40 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.alibaba.dubbo.registry.support;
 
-package com.alibaba.dubbo.config.spring.api;
+import java.util.Map;
 
-public interface HelloService {
-    String sayHello(String name);
+/**
+ * The Registration
+ *
+ * @since 2.6.6
+ */
+public interface Registration {
+
+    /**
+     * @return The service name
+     */
+    String getServiceName();
+
+    /**
+     * @return The IP address
+     */
+    String getIp();
+
+    /**
+     * @return The service port
+     */
+    int getPort();
+
+    /**
+     * @return The read-only metadata
+     */
+    Map<String, String> getMetadata();
+
+    @Override
+    boolean equals(Object o);
+
+    @Override
+    int hashCode();
 }
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/com/alibaba/dubbo/registry/support/ServiceInstanceRegistry.java b/dubbo-registry/dubbo-registry-api/src/main/java/com/alibaba/dubbo/registry/support/ServiceInstanceRegistry.java
new file mode 100644
index 0000000..d6b1d87
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/com/alibaba/dubbo/registry/support/ServiceInstanceRegistry.java
@@ -0,0 +1,474 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.registry.support;
+
+import com.alibaba.dubbo.common.Constants;
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.common.logger.Logger;
+import com.alibaba.dubbo.common.logger.LoggerFactory;
+import com.alibaba.dubbo.common.utils.StringUtils;
+import com.alibaba.dubbo.common.utils.UrlUtils;
+import com.alibaba.dubbo.registry.NotifyListener;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import static com.alibaba.dubbo.common.Constants.CONFIGURATORS_CATEGORY;
+import static com.alibaba.dubbo.common.Constants.CONSUMERS_CATEGORY;
+import static com.alibaba.dubbo.common.Constants.PROVIDERS_CATEGORY;
+import static com.alibaba.dubbo.common.Constants.ROUTERS_CATEGORY;
+import static java.lang.Long.getLong;
+import static java.lang.System.getProperty;
+
+/**
+ * {@link FailbackRegistry} extension that is used as the Oriented Service Instance registration, for
+ *
+ * @param <S> The actual type of service instance
+ * @since 2.6.6
+ */
+public abstract class ServiceInstanceRegistry<S> extends FailbackRegistry {
+
+    /**
+     * All supported categories
+     */
+    private static final String[] ALL_SUPPORTED_CATEGORIES = of(
+            PROVIDERS_CATEGORY,
+            CONSUMERS_CATEGORY,
+            ROUTERS_CATEGORY,
+            CONFIGURATORS_CATEGORY
+    );
+
+    private static final int CATEGORY_INDEX = 0;
+
+    private static final int SERVICE_INTERFACE_INDEX = CATEGORY_INDEX + 1;
+
+    private static final int SERVICE_VERSION_INDEX = SERVICE_INTERFACE_INDEX + 1;
+
+    private static final int SERVICE_GROUP_INDEX = SERVICE_VERSION_INDEX + 1;
+
+    private static final String WILDCARD = "*";
+
+    /**
+     * The separator for service name
+     */
+    private static final String SERVICE_NAME_SEPARATOR = getProperty("dubbo.service.name.separator", ":");
+
+    /**
+     * The interval in second of lookup service names(only for Dubbo-OPS)
+     */
+    private static final long LOOKUP_INTERVAL = getLong("dubbo.service.names.lookup.interval", 30);
+
+    protected final Logger logger = LoggerFactory.getLogger(getClass());
+
+    /**
+     * {@link ScheduledExecutorService} lookup service names(only for Dubbo-OPS)
+     */
+    private volatile ScheduledExecutorService serviceNamesScheduler;
+
+    public ServiceInstanceRegistry(URL url) {
+        super(url);
+    }
+
+    @Override
+    protected final void doRegister(URL url) {
+        String serviceName = getServiceName(url);
+        Registration registration = createRegistration(serviceName, url);
+        register(serviceName, toServiceInstance(registration), url);
+    }
+
+    @Override
+    protected final void doUnregister(URL url) {
+        String serviceName = getServiceName(url);
+        Registration registration = createRegistration(serviceName, url);
+        deregister(serviceName, toServiceInstance(registration), url);
+    }
+
+    @Override
+    protected final void doSubscribe(URL url, NotifyListener listener) {
+        Set<String> serviceNames = getServiceNames(url, listener);
+        doSubscribe(url, listener, serviceNames);
+    }
+
+    @Override
+    protected void doUnsubscribe(URL url, NotifyListener listener) {
+        if (isAdminProtocol(url)) {
+            shutdownServiceNamesLookup();
+        }
+    }
+
+    /**
+     * Adapts {@link Registration} to an actual service instance
+     *
+     * @param registration {@link Registration}
+     * @return
+     */
+    protected abstract S toServiceInstance(Registration registration);
+
+    /**
+     * Adapts {@link S} to an {@link Registration}
+     *
+     * @param serviceInstance {@link S}
+     * @return an {@link Registration}
+     */
+    protected abstract Registration toRegistration(S serviceInstance);
+
+    /**
+     * Register a {@link S service instance}
+     *
+     * @param serviceName     the service name
+     * @param serviceInstance {@link S service instance}
+     * @param url             Dubbo's {@link URL}
+     */
+    protected abstract void register(String serviceName, S serviceInstance, URL url);
+
+    /**
+     * Deregister a {@link DubboRegistration Dubbol registration}
+     *
+     * @param serviceName     the service name
+     * @param serviceInstance {@link S service instance}
+     * @param url             Dubbo's {@link URL}
+     */
+    protected abstract void deregister(String serviceName, S serviceInstance, URL url);
+
+    private void doSubscribe(final URL url, final NotifyListener listener, final Set<String> serviceNames) {
+        Collection<S> serviceInstances = new LinkedList<S>();
+
+        for (String serviceName : serviceNames) {
+            serviceInstances.addAll(findServiceInstances(serviceName));
+        }
+        notifySubscriber(url, listener, serviceInstances);
+    }
+
+    /**
+     * Notify the Healthy {@link DubboRegistration service instance} to subscriber.
+     *
+     * @param url              {@link URL}
+     * @param listener         {@link NotifyListener}
+     * @param serviceInstances all {@link S registrations}
+     */
+    private void notifySubscriber(URL url, NotifyListener listener, Collection<S> serviceInstances) {
+        Set<S> healthyServiceInstances = new LinkedHashSet<S>(serviceInstances);
+        // Healthy Instances
+        filterHealthyInstances(healthyServiceInstances);
+        List<URL> urls = buildURLs(url, healthyServiceInstances);
+        this.notify(url, listener, urls);
+    }
+
+    private void filterHealthyInstances(Collection<S> serviceInstances) {
+        filter(serviceInstances, new Filter<S>() {
+            @Override
+            public boolean accept(S serviceInstance) {
+                return filterHealthyRegistration(serviceInstance);
+            }
+        });
+    }
+
+    /**
+     * Find the {@link Collection} of {@link S service instances} by the service name
+     *
+     * @param serviceName the service name
+     * @return a {@link Collection} of {@link S service instances}
+     */
+    protected abstract Collection<S> findServiceInstances(String serviceName);
+
+    /**
+     * Filter Healthy the {@link S service instance}
+     *
+     * @param serviceInstance the {@link S service instance}
+     * @return if healthy , return <code>true</code>
+     */
+    protected abstract boolean filterHealthyRegistration(S serviceInstance);
+
+    private void shutdownServiceNamesLookup() {
+        if (serviceNamesScheduler != null) {
+            serviceNamesScheduler.shutdown();
+        }
+    }
+
+    private void scheduleServiceNamesLookup(final URL url,
+                                            final NotifyListener listener) {
+        if (serviceNamesScheduler == null) {
+            serviceNamesScheduler = Executors.newSingleThreadScheduledExecutor();
+            serviceNamesScheduler.scheduleAtFixedRate(new Runnable() {
+                @Override
+                public void run() {
+                    Set<String> serviceNames = findAllServiceNames();
+                    filter(serviceNames, new Filter<String>() {
+                        @Override
+                        public boolean accept(String serviceName) {
+                            boolean accepted = false;
+                            for (String category : ALL_SUPPORTED_CATEGORIES) {
+                                String prefix = category + SERVICE_NAME_SEPARATOR;
+                                if (serviceName.startsWith(prefix)) {
+                                    accepted = true;
+                                    break;
+                                }
+                            }
+                            return accepted;
+                        }
+                    });
+                    doSubscribe(url, listener, serviceNames);
+                }
+            }, LOOKUP_INTERVAL, LOOKUP_INTERVAL, TimeUnit.SECONDS);
+        }
+    }
+
+    /**
+     * Find all service names
+     *
+     * @return all service names
+     */
+    protected abstract Set<String> findAllServiceNames();
+
+    private List<URL> buildURLs(URL consumerURL, Collection<S> serviceInstances) {
+        if (serviceInstances.isEmpty()) {
+            return Collections.emptyList();
+        }
+        List<URL> urls = new LinkedList<URL>();
+        for (S serviceInstance : serviceInstances) {
+            Registration registration = toRegistration(serviceInstance);
+            URL url = buildURL(registration);
+            if (UrlUtils.isMatch(consumerURL, url)) {
+                urls.add(url);
+            }
+        }
+        return urls;
+    }
+
+    private URL buildURL(Registration registration) {
+        URL url = new URL(registration.getMetadata().get(Constants.PROTOCOL_KEY),
+                registration.getIp(), registration.getPort(),
+                registration.getMetadata());
+        return url;
+    }
+
+    /**
+     * Get the service names for Dubbo OPS
+     *
+     * @param url {@link URL}
+     * @return non-null
+     */
+    private Set<String> getSubscribedServiceNamesForOps(URL url) {
+        Set<String> serviceNames = findAllServiceNames();
+        filterServiceNames(serviceNames, url);
+        return serviceNames;
+    }
+
+    private <T> void filter(Collection<T> collection, Filter<T> filter) {
+        Iterator<T> iterator = collection.iterator();
+        while (iterator.hasNext()) {
+            T data = iterator.next();
+            if (!filter.accept(data)) { // remove if not accept
+                iterator.remove();
+            }
+        }
+    }
+
+    private void filterServiceNames(Set<String> serviceNames, URL url) {
+
+        final String[] categories = getCategories(url);
+
+        final String targetServiceInterface = url.getServiceInterface();
+
+        final String targetVersion = url.getParameter(Constants.VERSION_KEY);
+
+        final String targetGroup = url.getParameter(Constants.GROUP_KEY);
+
+        filter(serviceNames, new Filter<String>() {
+            @Override
+            public boolean accept(String serviceName) {
+                // split service name to segments
+                // (required) segments[0] = category
+                // (required) segments[1] = serviceInterface
+                // (required) segments[2] = version
+                // (optional) segments[3] = group
+                String[] segments = getServiceSegments(serviceName);
+                int length = segments.length;
+                if (length < 4) { // must present 4 segments or more
+                    return false;
+                }
+
+                String category = getCategory(segments);
+                if (Arrays.binarySearch(categories, category) > -1) { // no match category
+                    return false;
+                }
+
+                String serviceInterface = getServiceInterface(segments);
+                if (!WILDCARD.equals(targetServiceInterface)
+                        && !StringUtils.isEquals(targetServiceInterface, serviceInterface)) { // no match interface
+                    return false;
+                }
+
+                String version = getServiceVersion(segments);
+                if (!WILDCARD.equals(targetVersion)
+                        && !StringUtils.isEquals(targetVersion, version)) { // no match service
+                    // version
+                    return false;
+                }
+
+                String group = getServiceGroup(segments);
+                if (group != null && !WILDCARD.equals(targetGroup)
+                        && !StringUtils.isEquals(targetGroup, group)) { // no match service
+                    // group
+                    return false;
+                }
+
+                return true;
+            }
+        });
+    }
+
+    protected Registration createRegistration(String serviceName, URL url) {
+        // Append default category if absent
+        String category = url.getParameter(Constants.CATEGORY_KEY,
+                Constants.DEFAULT_CATEGORY);
+        URL newURL = url.addParameter(Constants.CATEGORY_KEY, category);
+        newURL = newURL.addParameter(Constants.PROTOCOL_KEY, url.getProtocol());
+        String ip = url.getHost();
+        int port = url.getPort();
+        DubboRegistration registration = new DubboRegistration();
+        registration.setServiceName(serviceName);
+        registration.setIp(ip);
+        registration.setPort(port);
+        registration.setMetadata(new LinkedHashMap<String, String>(newURL.getParameters()));
+
+        return registration;
+    }
+
+    /**
+     * Get the categories from {@link URL}
+     *
+     * @param url {@link URL}
+     * @return non-null array
+     */
+    private String[] getCategories(URL url) {
+        return Constants.ANY_VALUE.equals(url.getServiceInterface())
+                ? ALL_SUPPORTED_CATEGORIES
+                : of(Constants.DEFAULT_CATEGORY);
+    }
+
+    /**
+     * A filter
+     */
+    private interface Filter<T> {
+
+        /**
+         * Tests whether or not the specified data should be accepted.
+         *
+         * @param data The data to be tested
+         * @return <code>true</code> if and only if <code>data</code> should be accepted
+         */
+        boolean accept(T data);
+
+    }
+
+    /**
+     * Get the subscribed service names from the specified {@link URL url}
+     *
+     * @param url      {@link URL}
+     * @param listener {@link NotifyListener}
+     * @return non-null
+     */
+    private Set<String> getServiceNames(URL url, NotifyListener listener) {
+        if (isAdminProtocol(url)) {
+            scheduleServiceNamesLookup(url, listener);
+            return getSubscribedServiceNamesForOps(url);
+        } else {
+            return getServiceNames(url);
+        }
+    }
+
+    private Set<String> getServiceNames(URL url) {
+        String[] categories = getCategories(url);
+        Set<String> serviceNames = new LinkedHashSet<String>(categories.length);
+        for (String category : categories) {
+            final String serviceName = getServiceName(url, category);
+            serviceNames.add(serviceName);
+        }
+        return serviceNames;
+    }
+
+    private boolean isAdminProtocol(URL url) {
+        return Constants.ADMIN_PROTOCOL.equals(url.getProtocol());
+    }
+
+    /**
+     * Get the service name
+     *
+     * @param url {@link URL}
+     * @return non-null
+     */
+    public static String getServiceName(URL url) {
+        String category = url.getParameter(Constants.CATEGORY_KEY,
+                Constants.DEFAULT_CATEGORY);
+        return getServiceName(url, category);
+    }
+
+    private static String getServiceName(URL url, String category) {
+        StringBuilder serviceNameBuilder = new StringBuilder(category);
+        appendIfPresent(serviceNameBuilder, url, Constants.INTERFACE_KEY);
+        appendIfPresent(serviceNameBuilder, url, Constants.VERSION_KEY);
+        appendIfPresent(serviceNameBuilder, url, Constants.GROUP_KEY);
+        return serviceNameBuilder.toString();
+    }
+
+    private static void appendIfPresent(StringBuilder target, URL url,
+                                        String parameterName) {
+        String parameterValue = url.getParameter(parameterName);
+        appendIfPresent(target, parameterValue);
+    }
+
+    public static String[] getServiceSegments(String serviceName) {
+        return serviceName.split(SERVICE_NAME_SEPARATOR);
+    }
+
+    public static String getCategory(String[] segments) {
+        return segments[CATEGORY_INDEX];
+    }
+
+    public static String getServiceInterface(String[] segments) {
+        return segments[SERVICE_INTERFACE_INDEX];
+    }
+
+    public static String getServiceVersion(String[] segments) {
+        return segments[SERVICE_VERSION_INDEX];
+    }
+
+    public static String getServiceGroup(String[] segments) {
+        return segments.length > 4 ? segments[SERVICE_GROUP_INDEX] : null;
+    }
+
+    private static <T> T[] of(T... values) {
+        return values;
+    }
+
+    private static void appendIfPresent(StringBuilder target, String parameterValue) {
+        if (StringUtils.isNotEmpty(parameterValue)) {
+            target.append(SERVICE_NAME_SEPARATOR).append(parameterValue);
+        }
+    }
+}
diff --git a/dubbo-registry/dubbo-registry-nacos/pom.xml b/dubbo-registry/dubbo-registry-nacos/pom.xml
new file mode 100644
index 0000000..53b7e72
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/pom.xml
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>dubbo-registry</artifactId>
+        <groupId>com.alibaba</groupId>
+        <version>2.6.6-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-registry-nacos</artifactId>
+
+    <properties>
+        <nacos.version>0.6.2</nacos.version>
+    </properties>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>dubbo-registry-api</artifactId>
+            <version>${project.version}</version>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>dubbo-common</artifactId>
+            <version>${project.version}</version>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba.nacos</groupId>
+            <artifactId>nacos-client</artifactId>
+            <version>${nacos.version}</version>
+            <optional>true</optional>
+        </dependency>
+
+        <!-- Test Libraries -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>dubbo-config-api</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>dubbo-serialization-hessian2</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>dubbo-config-spring</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>dubbo-rpc-dubbo</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>dubbo-remoting-netty4</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>1.2.3</version>
+            <scope>test</scope>
+        </dependency>
+
+        <!-- REST support dependencies -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>dubbo-rpc-rest</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-jaxrs</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-client</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-netty4</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-jackson-provider</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-jaxb-provider</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+
+
+    </dependencies>
+</project>
diff --git a/dubbo-registry/dubbo-registry-nacos/src/main/java/com/alibaba/dubbo/registry/nacos/NacosRegistry.java b/dubbo-registry/dubbo-registry-nacos/src/main/java/com/alibaba/dubbo/registry/nacos/NacosRegistry.java
new file mode 100644
index 0000000..621e7b4
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/main/java/com/alibaba/dubbo/registry/nacos/NacosRegistry.java
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.registry.nacos;
+
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.registry.Registry;
+import com.alibaba.dubbo.registry.support.Registration;
+import com.alibaba.dubbo.registry.support.ServiceInstanceRegistry;
+import com.alibaba.nacos.api.exception.NacosException;
+import com.alibaba.nacos.api.naming.NamingService;
+import com.alibaba.nacos.api.naming.listener.EventListener;
+import com.alibaba.nacos.api.naming.pojo.Instance;
+import com.alibaba.nacos.api.naming.pojo.ListView;
+
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * Nacos {@link Registry}
+ *
+ * @since 2.6.6
+ */
+public class NacosRegistry extends ServiceInstanceRegistry<Instance> {
+
+    /**
+     * The pagination size of query for Nacos service names(only for Dubbo-OPS)
+     */
+    private static final int PAGINATION_SIZE = Integer.getInteger("nacos.service.names.pagination.size", 100);
+
+    private final NamingService namingService;
+
+    private final ConcurrentMap<String, EventListener> nacosListeners;
+
+    public NacosRegistry(URL url, NamingService namingService) {
+        super(url);
+        this.namingService = namingService;
+        this.nacosListeners = new ConcurrentHashMap<String, EventListener>();
+    }
+
+
+    @Override
+    protected Instance toServiceInstance(Registration registration) {
+        Instance instance = new Instance();
+        instance.setServiceName(registration.getServiceName());
+        instance.setIp(registration.getIp());
+        instance.setPort(registration.getPort());
+        instance.setMetadata(registration.getMetadata());
+        return instance;
+    }
+
+    @Override
+    protected Registration toRegistration(final Instance serviceInstance) {
+        return new Registration() {
+
+            @Override
+            public String getServiceName() {
+                return serviceInstance.getServiceName();
+            }
+
+            @Override
+            public String getIp() {
+                return serviceInstance.getIp();
+            }
+
+            @Override
+            public int getPort() {
+                return serviceInstance.getPort();
+            }
+
+            @Override
+            public Map<String, String> getMetadata() {
+                return serviceInstance.getMetadata();
+            }
+        };
+    }
+
+    @Override
+    protected void register(final String serviceName, final Instance serviceInstance, URL url) {
+        execute(new NamingServiceCallback() {
+            @Override
+            public void callback(NamingService namingService) throws NacosException {
+                namingService.registerInstance(serviceName, serviceInstance);
+            }
+        });
+    }
+
+    @Override
+    protected void deregister(final String serviceName, final Instance serviceInstance, URL url) {
+        execute(new NamingServiceCallback() {
+            @Override
+            public void callback(NamingService namingService) throws NacosException {
+                namingService.deregisterInstance(serviceName, serviceInstance.getIp(), serviceInstance.getPort());
+            }
+        });
+    }
+
+    @Override
+    protected Collection<Instance> findServiceInstances(final String serviceName) {
+        final Collection<Instance> instances = new LinkedList<Instance>();
+        execute(new NamingServiceCallback() {
+            @Override
+            public void callback(NamingService namingService) throws NacosException {
+                instances.addAll(namingService.getAllInstances(serviceName));
+            }
+        });
+        return instances;
+    }
+
+    @Override
+    protected boolean filterHealthyRegistration(Instance serviceInstance) {
+        return serviceInstance.isEnabled();
+    }
+
+    @Override
+    protected Set<String> findAllServiceNames() {
+        final Set<String> serviceNames = new LinkedHashSet<String>();
+
+        execute(new NamingServiceCallback() {
+            @Override
+            public void callback(NamingService namingService) throws NacosException {
+
+                int pageIndex = 1;
+                ListView<String> listView = namingService.getServicesOfServer(pageIndex, PAGINATION_SIZE);
+                // First page data
+                List<String> firstPageData = listView.getData();
+                // Append first page into list
+                serviceNames.addAll(firstPageData);
+                // the total count
+                int count = listView.getCount();
+                // the number of pages
+                int pageNumbers = count / PAGINATION_SIZE;
+                int remainder = count % PAGINATION_SIZE;
+                // remain
+                if (remainder > 0) {
+                    pageNumbers += 1;
+                }
+                // If more than 1 page
+                while (pageIndex < pageNumbers) {
+                    listView = namingService.getServicesOfServer(++pageIndex, PAGINATION_SIZE);
+                    serviceNames.addAll(listView.getData());
+                }
+
+            }
+        });
+
+        return serviceNames;
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return "UP".equals(namingService.getServerStatus());
+    }
+
+    private void execute(NamingServiceCallback callback) {
+        try {
+            callback.callback(namingService);
+        } catch (NacosException e) {
+            if (logger.isErrorEnabled()) {
+                logger.error(e.getErrMsg(), e);
+            }
+        }
+    }
+
+    /**
+     * {@link NamingService} Callback
+     */
+    interface NamingServiceCallback {
+
+        /**
+         * Callback
+         *
+         * @param namingService {@link NamingService}
+         * @throws NacosException
+         */
+        void callback(NamingService namingService) throws NacosException;
+
+    }
+}
diff --git a/dubbo-registry/dubbo-registry-nacos/src/main/java/com/alibaba/dubbo/registry/nacos/NacosRegistryFactory.java b/dubbo-registry/dubbo-registry-nacos/src/main/java/com/alibaba/dubbo/registry/nacos/NacosRegistryFactory.java
new file mode 100644
index 0000000..56de760
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/main/java/com/alibaba/dubbo/registry/nacos/NacosRegistryFactory.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.registry.nacos;
+
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.registry.Registry;
+import com.alibaba.dubbo.registry.RegistryFactory;
+import com.alibaba.dubbo.registry.support.AbstractRegistryFactory;
+import com.alibaba.nacos.api.NacosFactory;
+import com.alibaba.nacos.api.exception.NacosException;
+import com.alibaba.nacos.api.naming.NamingService;
+import com.alibaba.nacos.client.naming.utils.StringUtils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Properties;
+
+import static com.alibaba.dubbo.common.Constants.BACKUP_KEY;
+import static com.alibaba.nacos.api.PropertyKeyConst.ACCESS_KEY;
+import static com.alibaba.nacos.api.PropertyKeyConst.CLUSTER_NAME;
+import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT;
+import static com.alibaba.nacos.api.PropertyKeyConst.NAMESPACE;
+import static com.alibaba.nacos.api.PropertyKeyConst.SECRET_KEY;
+import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
+import static com.alibaba.nacos.client.naming.utils.UtilAndComs.NACOS_NAMING_LOG_NAME;
+
+/**
+ * Nacos {@link RegistryFactory}
+ *
+ * @since 2.6.6
+ */
+public class NacosRegistryFactory extends AbstractRegistryFactory {
+
+    private final Logger logger = LoggerFactory.getLogger(getClass());
+
+    protected Registry createRegistry(URL url) {
+        return new NacosRegistry(url, buildNamingService(url));
+    }
+
+    private NamingService buildNamingService(URL url) {
+        Properties nacosProperties = buildNacosProperties(url);
+        NamingService namingService = null;
+        try {
+            namingService = NacosFactory.createNamingService(nacosProperties);
+        } catch (NacosException e) {
+            if (logger.isErrorEnabled()) {
+                logger.error(e.getErrMsg(), e);
+            }
+            throw new IllegalStateException(e);
+        }
+        return namingService;
+    }
+
+    private Properties buildNacosProperties(URL url) {
+        Properties properties = new Properties();
+        setServerAddr(url, properties);
+        setProperties(url, properties);
+        return properties;
+    }
+
+    private void setServerAddr(URL url, Properties properties) {
+        StringBuilder serverAddrBuilder =
+                new StringBuilder(url.getHost()) // Host
+                        .append(":")
+                        .append(url.getPort()); // Port
+
+        // Append backup parameter as other servers
+        String backup = url.getParameter(BACKUP_KEY);
+        if (backup != null) {
+            serverAddrBuilder.append(",").append(backup);
+        }
+
+        String serverAddr = serverAddrBuilder.toString();
+        properties.put(SERVER_ADDR, serverAddr);
+    }
+
+    private void setProperties(URL url, Properties properties) {
+        putPropertyIfAbsent(url, properties, NAMESPACE);
+        putPropertyIfAbsent(url, properties, NACOS_NAMING_LOG_NAME);
+        putPropertyIfAbsent(url, properties, ENDPOINT);
+        putPropertyIfAbsent(url, properties, NAMESPACE);
+        putPropertyIfAbsent(url, properties, ACCESS_KEY);
+        putPropertyIfAbsent(url, properties, SECRET_KEY);
+        putPropertyIfAbsent(url, properties, CLUSTER_NAME);
+    }
+
+    private void putPropertyIfAbsent(URL url, Properties properties, String propertyName) {
+        String propertyValue = url.getParameter(propertyName);
+        if (StringUtils.isNotEmpty(propertyValue)) {
+            properties.setProperty(propertyName, propertyValue);
+        }
+    }
+}
diff --git a/dubbo-registry/dubbo-registry-nacos/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.registry.RegistryFactory b/dubbo-registry/dubbo-registry-nacos/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.registry.RegistryFactory
new file mode 100644
index 0000000..370cd4a
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.registry.RegistryFactory
@@ -0,0 +1 @@
+nacos=com.alibaba.dubbo.registry.nacos.NacosRegistryFactory
\ No newline at end of file
diff --git a/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/consumer/DemoServiceConsumerBootstrap.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/consumer/DemoServiceConsumerBootstrap.java
new file mode 100644
index 0000000..c61dcb5
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/consumer/DemoServiceConsumerBootstrap.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.demo.consumer;
+
+import com.alibaba.dubbo.config.annotation.Reference;
+import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
+import com.alibaba.dubbo.demo.service.DemoService;
+
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.PropertySource;
+
+import javax.annotation.PostConstruct;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * {@link DemoService} consumer demo
+ */
+@EnableDubbo
+@PropertySource(value = "classpath:/consumer-config.properties")
+public class DemoServiceConsumerBootstrap {
+
+    @Reference(version = "${demo.service.version}")
+    private DemoService demoService;
+
+    @Reference(version = "${demo.service.version}", protocol = "rest")
+    private DemoService restDemoService;
+
+    @PostConstruct
+    public void init() throws InterruptedException {
+        for (int j = 0; j < 10; j++) {
+            System.out.println(demoService.sayName("小马哥(mercyblitz)"));
+            System.out.println(restDemoService.sayName("小马哥(mercyblitz)"));
+        }
+        Thread.sleep(TimeUnit.SECONDS.toMillis(5));
+    }
+
+    public static void main(String[] args) throws IOException {
+        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
+        context.register(DemoServiceConsumerBootstrap.class);
+        context.refresh();
+        System.in.read();
+        context.close();
+    }
+}
diff --git a/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/consumer/DemoServiceConsumerXmlBootstrap.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/consumer/DemoServiceConsumerXmlBootstrap.java
new file mode 100644
index 0000000..65b7bef
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/consumer/DemoServiceConsumerXmlBootstrap.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.demo.consumer;
+
+import com.alibaba.dubbo.demo.service.DemoService;
+
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import java.io.IOException;
+
+/**
+ * {@link DemoService} consumer demo XML bootstrap
+ */
+public class DemoServiceConsumerXmlBootstrap {
+
+    public static void main(String[] args) throws IOException {
+        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
+        context.setConfigLocation("/META-INF/spring/dubbo-consumer-context.xml");
+        context.refresh();
+        System.out.println("DemoService consumer (XML) is starting...");
+        DemoService demoService = context.getBean("demoService", DemoService.class);
+        for (int i = 0; i < 10; i++) {
+            System.out.println(demoService.sayName("小马哥(mercyblitz)"));
+        }
+        System.in.read();
+        context.close();
+    }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingsRegistrarTest.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/provider/DemoServiceProviderBootstrap.java
similarity index 51%
copy from dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingsRegistrarTest.java
copy to dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/provider/DemoServiceProviderBootstrap.java
index a73dbf2..f9cd797 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/context/annotation/DubboConfigBindingsRegistrarTest.java
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/provider/DemoServiceProviderBootstrap.java
@@ -14,47 +14,28 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.alibaba.dubbo.config.spring.context.annotation;
+package com.alibaba.dubbo.demo.provider;
 
-import com.alibaba.dubbo.config.ApplicationConfig;
+import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
+import com.alibaba.dubbo.demo.service.DemoService;
 
-import org.junit.Assert;
-import org.junit.Test;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 import org.springframework.context.annotation.PropertySource;
 
+import java.io.IOException;
+
 /**
- * {@link DubboConfigBindingsRegistrar} Test
- *
- * @since DubboConfigBindingsRegistrar
+ * {@link DemoService} provider demo
  */
-public class DubboConfigBindingsRegistrarTest {
-
-    @Test
-    public void test() {
+@EnableDubbo(scanBasePackages = "com.alibaba.dubbo.demo.service")
+@PropertySource(value = "classpath:/provider-config.properties")
+public class DemoServiceProviderBootstrap {
 
+    public static void main(String[] args) throws IOException {
         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
-
-        context.register(TestConfig.class);
-
+        context.register(DemoServiceProviderBootstrap.class);
         context.refresh();
-
-        ApplicationConfig applicationConfig = context.getBean("applicationBean", ApplicationConfig.class);
-
-        Assert.assertEquals("dubbo-demo-application", applicationConfig.getName());
-
-        Assert.assertEquals(2, context.getBeansOfType(ApplicationConfig.class).size());
-
+        System.out.println("DemoService provider is starting...");
+        System.in.read();
     }
-
-
-    @EnableDubboConfigBindings({
-            @EnableDubboConfigBinding(prefix = "${application.prefix}", type = ApplicationConfig.class),
-            @EnableDubboConfigBinding(prefix = "dubbo.applications.applicationBean", type = ApplicationConfig.class)
-    })
-    @PropertySource("META-INF/config.properties")
-    private static class TestConfig {
-
-    }
-
 }
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/provider/DemoServiceProviderXmlBootstrap.java
similarity index 54%
copy from dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
copy to dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/provider/DemoServiceProviderXmlBootstrap.java
index 1feb2bd..964adbc 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/provider/DemoServiceProviderXmlBootstrap.java
@@ -14,9 +14,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.alibaba.dubbo.demo.provider;
 
-package com.alibaba.dubbo.config.spring.api;
+import com.alibaba.dubbo.demo.service.DemoService;
 
-public interface HelloService {
-    String sayHello(String name);
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import java.io.IOException;
+
+/**
+ * {@link DemoService} provider demo XML bootstrap
+ */
+public class DemoServiceProviderXmlBootstrap {
+
+    public static void main(String[] args) throws IOException {
+        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
+        context.setConfigLocation("/META-INF/spring/dubbo-provider-context.xml");
+        context.refresh();
+        System.out.println("DemoService provider (XML) is starting...");
+        System.in.read();
+    }
 }
diff --git a/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/service/DefaultService.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/service/DefaultService.java
new file mode 100644
index 0000000..0ff9ada
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/service/DefaultService.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.demo.service;
+
+import com.alibaba.dubbo.config.annotation.Service;
+import com.alibaba.dubbo.rpc.RpcContext;
+
+import org.springframework.beans.factory.annotation.Value;
+
+
+/**
+ * Default {@link DemoService}
+ *
+ * @since 2.6.5
+ */
+@Service(version = "${demo.service.version}")
+public class DefaultService implements DemoService {
+
+    @Value("${demo.service.name}")
+    private String serviceName;
+
+    public String sayName(String name) {
+        RpcContext rpcContext = RpcContext.getContext();
+        return String.format("Service [name :%s , protocol: %s , port : %d] %s(\"%s\") : Hello,%s",
+                serviceName,
+                rpcContext.getUrl().getProtocol(),
+                rpcContext.getLocalPort(),
+                rpcContext.getMethodName(),
+                name,
+                name);
+    }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/service/DemoService.java
similarity index 74%
copy from dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
copy to dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/service/DemoService.java
index 1feb2bd..381540e 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/demo/service/DemoService.java
@@ -14,9 +14,21 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.alibaba.dubbo.demo.service;
 
-package com.alibaba.dubbo.config.spring.api;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.QueryParam;
 
-public interface HelloService {
-    String sayHello(String name);
-}
+/**
+ * DemoService
+ *
+ * @since 2.6.5
+ */
+@Path("/demo-service")
+public interface DemoService {
+
+    @GET
+    String sayName(@QueryParam("name") String name);
+
+}
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/registry/nacos/NacosRegistryFactoryTest.java
similarity index 84%
copy from dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
copy to dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/registry/nacos/NacosRegistryFactoryTest.java
index 1feb2bd..8f7a152 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/registry/nacos/NacosRegistryFactoryTest.java
@@ -14,9 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.alibaba.dubbo.registry.nacos;
 
-package com.alibaba.dubbo.config.spring.api;
-
-public interface HelloService {
-    String sayHello(String name);
+/**
+ * {@link NacosRegistryFactory} Test
+ *
+ * @since 2.6.5
+ */
+public class NacosRegistryFactoryTest {
 }
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/registry/nacos/NacosRegistryTest.java
similarity index 68%
copy from dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
copy to dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/registry/nacos/NacosRegistryTest.java
index 1feb2bd..3ff055b 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/api/HelloService.java
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/com/alibaba/dubbo/registry/nacos/NacosRegistryTest.java
@@ -14,9 +14,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.alibaba.dubbo.registry.nacos;
 
-package com.alibaba.dubbo.config.spring.api;
+/**
+ * {@link NacosRegistry} Test
+ *
+ * @since 2.6.5
+ */
+public class NacosRegistryTest {
+
+    // Test case Dubbo OPS :
+    // URL : admin://30.5.124.12?category=providers,consumers,routers,configurators&check=false&classifier=*&enabled=*&group=*&interface=*&version=*
+    public void testDoSubscribeForDubboOps() {
+
+    }
 
-public interface HelloService {
-    String sayHello(String name);
 }
diff --git a/dubbo-registry/dubbo-registry-nacos/src/test/resources/META-INF/spring/dubbo-consumer-context.xml b/dubbo-registry/dubbo-registry-nacos/src/test/resources/META-INF/spring/dubbo-consumer-context.xml
new file mode 100644
index 0000000..0d47053
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/resources/META-INF/spring/dubbo-consumer-context.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd        http://dubbo.apache.org/schema/dubbo        http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
+
+    <!-- 提供方应用信息,用于计算依赖关系 -->
+    <dubbo:application name="dubbo-consumer-xml-demo"/>
+
+    <!-- 使用 Nacos 注册中心 -->
+    <dubbo:registry address="nacos://127.0.0.1:8848"/>
+
+    <!-- 引用服务接口 -->
+    <dubbo:reference id="demoService" interface="com.alibaba.dubbo.demo.service.DemoService" version="2.0.0"/>
+
+</beans>
\ No newline at end of file
diff --git a/dubbo-registry/dubbo-registry-nacos/src/test/resources/META-INF/spring/dubbo-provider-context.xml b/dubbo-registry/dubbo-registry-nacos/src/test/resources/META-INF/spring/dubbo-provider-context.xml
new file mode 100644
index 0000000..acf08a5
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/resources/META-INF/spring/dubbo-provider-context.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd        http://dubbo.apache.org/schema/dubbo        http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
+
+    <!-- 提供方应用信息,用于计算依赖关系 -->
+    <dubbo:application name="dubbo-provider-xml-demo"/>
+
+    <!-- 使用 Nacos 注册中心 -->
+    <dubbo:registry address="nacos://127.0.0.1:8848"/>
+
+    <!-- 用dubbo协议在随机端口暴露服务 -->
+    <dubbo:protocol name="dubbo" port="-1"/>
+
+    <!-- 声明需要暴露的服务接口 -->
+    <dubbo:service interface="com.alibaba.dubbo.demo.service.DemoService" ref="demoService" version="2.0.0"/>
+
+    <!-- 和本地bean一样实现服务 -->
+    <bean id="demoService" class="com.alibaba.dubbo.demo.service.DefaultService"/>
+</beans>
\ No newline at end of file
diff --git a/dubbo-registry/dubbo-registry-nacos/src/test/resources/consumer-config.properties b/dubbo-registry/dubbo-registry-nacos/src/test/resources/consumer-config.properties
new file mode 100644
index 0000000..d32e6e8
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/resources/consumer-config.properties
@@ -0,0 +1,6 @@
+## Dubbo Application info
+dubbo.application.name=dubbo-consumer-demo
+## Nacos registry address
+dubbo.registry.address=nacos://127.0.0.1:8848
+# @Reference version
+demo.service.version=1.0.0
\ No newline at end of file
diff --git a/dubbo-registry/dubbo-registry-nacos/src/test/resources/provider-config.properties b/dubbo-registry/dubbo-registry-nacos/src/test/resources/provider-config.properties
new file mode 100644
index 0000000..e2dd335
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/resources/provider-config.properties
@@ -0,0 +1,14 @@
+## Dubbo Application info
+dubbo.application.name=dubbo-provider-demo
+## Nacos registry address
+dubbo.registry.protocol=nacos
+dubbo.registry.address=127.0.0.1:8848
+## Exports multiple protocols
+### Dubbo Protocol using random port
+dubbo.protocols.dubbo.port=-1
+### REST protocol
+dubbo.protocols.rest.port=9090
+dubbo.protocols.rest.server=netty
+# Provider @Service info
+demo.service.version=1.0.0
+demo.service.name=demoService
\ No newline at end of file
diff --git a/dubbo-registry/pom.xml b/dubbo-registry/pom.xml
index b268a88..fe3a7f8 100644
--- a/dubbo-registry/pom.xml
+++ b/dubbo-registry/pom.xml
@@ -34,5 +34,6 @@
         <module>dubbo-registry-multicast</module>
         <module>dubbo-registry-zookeeper</module>
         <module>dubbo-registry-redis</module>
+        <module>dubbo-registry-nacos</module>
     </modules>
 </project>
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/com/alibaba/dubbo/rpc/protocol/rest/RestProtocol.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/com/alibaba/dubbo/rpc/protocol/rest/RestProtocol.java
index 78b5deb..be4225c 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/com/alibaba/dubbo/rpc/protocol/rest/RestProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/com/alibaba/dubbo/rpc/protocol/rest/RestProtocol.java
@@ -25,6 +25,7 @@ import com.alibaba.dubbo.remoting.http.servlet.ServletManager;
 import com.alibaba.dubbo.rpc.RpcException;
 import com.alibaba.dubbo.rpc.StaticContext;
 import com.alibaba.dubbo.rpc.protocol.AbstractProxyProtocol;
+
 import org.apache.http.HeaderElement;
 import org.apache.http.HeaderElementIterator;
 import org.apache.http.HttpResponse;
@@ -231,8 +232,13 @@ public class RestProtocol extends AbstractProxyProtocol {
     }
 
     protected String getContextPath(URL url) {
-        int pos = url.getPath().lastIndexOf("/");
-        return pos > 0 ? url.getPath().substring(0, pos) : "";
+        String path = url.getPath();
+        if (path != null) {
+            int pos = url.getPath().lastIndexOf("/");
+            return pos > 0 ? url.getPath().substring(0, pos) : "";
+        } else {
+            return "";
+        }
     }
 
     protected class ConnectionMonitor extends Thread {