diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationBeanNameBuilder.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationBeanNameBuilder.java new file mode 100644 index 00000000000..610058acd71 --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/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 org.apache.dubbo.config.spring.beans.factory.annotation; + +import org.apache.dubbo.common.Constants; +import org.apache.dubbo.config.annotation.Reference; +import org.apache.dubbo.config.annotation.Service; +import org.apache.dubbo.registry.Registry; + +import org.springframework.core.env.Environment; + +import static org.apache.dubbo.common.Constants.CONSUMERS_CATEGORY; +import static org.apache.dubbo.common.Constants.DEFAULT_PROTOCOL; +import static org.apache.dubbo.common.Constants.PROVIDERS_CATEGORY; +import static org.apache.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} + *
+ * 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. + *
+ * The pattern of bean name : ${category}:${protocol}:${serviceInterface}:${version}:${group}. + *
+ * ${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 protocols
== null
, 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/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
index e02c1e10cc5..94bf9e800fe 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
@@ -188,7 +188,9 @@ protected String buildInjectedObjectCacheKey(Reference reference, Object bean, S
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());
}
@@ -261,4 +263,4 @@ public void destroy() throws Exception {
this.injectedFieldReferenceBeanCache.clear();
this.injectedMethodReferenceBeanCache.clear();
}
-}
+}
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
index 22fa70422d5..532026de3d1 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
@@ -18,7 +18,6 @@
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.config.MethodConfig;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.spring.ServiceBean;
import org.apache.dubbo.config.spring.context.annotation.DubboClassPathBeanDefinitionScanner;
@@ -290,8 +289,9 @@ private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, Bean
*/
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();
@@ -316,8 +316,9 @@ private Class> resolveServiceInterfaceClass(Class> annotatedServiceBeanClass
}
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];
@@ -435,11 +436,6 @@ private AbstractBeanDefinition buildServiceBeanDefinition(Service service, Class
builder.addPropertyValue("protocols", protocolRuntimeBeanReferences);
}
- Listtrue
if and only if data
+ * should be accepted
+ */
+ boolean accept(T data);
+
+ }
+
+ /**
+ * {@link NamingService} Callback
+ *
+ * @since 2.6.5
+ */
+ 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/org/apache/dubbo/registry/nacos/NacosRegistryFactory.java b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistryFactory.java
new file mode 100644
index 00000000000..1470c198932
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/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 org.apache.dubbo.registry.nacos;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.registry.Registry;
+import org.apache.dubbo.registry.RegistryFactory;
+import org.apache.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.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;
+import static org.apache.dubbo.common.Constants.BACKUP_KEY;
+
+/**
+ * Nacos {@link RegistryFactory}
+ *
+ * @since 2.6.5
+ */
+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/internal/org.apache.dubbo.registry.RegistryFactory b/dubbo-registry/dubbo-registry-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory
new file mode 100644
index 00000000000..bb754674978
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory
@@ -0,0 +1 @@
+nacos=org.apache.dubbo.registry.nacos.NacosRegistryFactory
\ No newline at end of file
diff --git a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/demo/consumer/DemoServiceConsumerBootstrap.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/demo/consumer/DemoServiceConsumerBootstrap.java
new file mode 100644
index 00000000000..b411d4a80f0
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/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 org.apache.dubbo.demo.consumer;
+
+import org.apache.dubbo.config.annotation.Reference;
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.apache.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/org/apache/dubbo/demo/consumer/DemoServiceConsumerXmlBootstrap.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/demo/consumer/DemoServiceConsumerXmlBootstrap.java
new file mode 100644
index 00000000000..cc25f8c1355
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/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 org.apache.dubbo.demo.consumer;
+
+import org.apache.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-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/demo/provider/DemoServiceProviderBootstrap.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/demo/provider/DemoServiceProviderBootstrap.java
new file mode 100644
index 00000000000..c1d2ec4f0f5
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/demo/provider/DemoServiceProviderBootstrap.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.demo.provider;
+
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.apache.dubbo.demo.service.DemoService;
+
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.PropertySource;
+
+import java.io.IOException;
+
+/**
+ * {@link DemoService} provider demo
+ */
+@EnableDubbo(scanBasePackages = "org.apache.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(DemoServiceProviderBootstrap.class);
+ context.refresh();
+ System.out.println("DemoService provider is starting...");
+ System.in.read();
+ }
+}
diff --git a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/demo/provider/DemoServiceProviderXmlBootstrap.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/demo/provider/DemoServiceProviderXmlBootstrap.java
new file mode 100644
index 00000000000..0a37f3fabe9
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/demo/provider/DemoServiceProviderXmlBootstrap.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.demo.provider;
+
+import org.apache.dubbo.demo.service.DemoService;
+
+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/org/apache/dubbo/demo/service/DefaultService.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/demo/service/DefaultService.java
new file mode 100644
index 00000000000..56393ef3961
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/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 org.apache.dubbo.demo.service;
+
+import org.apache.dubbo.config.annotation.Service;
+import org.apache.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-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/demo/service/DemoService.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/demo/service/DemoService.java
new file mode 100644
index 00000000000..0c808779311
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/demo/service/DemoService.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.demo.service;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.QueryParam;
+
+/**
+ * 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-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 00000000000..3fa32d77b5f
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/resources/META-INF/spring/dubbo-consumer-context.xml
@@ -0,0 +1,15 @@
+
+