You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by al...@apache.org on 2021/06/29 02:22:33 UTC
[dubbo] 01/02: Support generic call by reference without interface
class locally (#8159)
This is an automated email from the ASF dual-hosted git repository.
albumenj pushed a commit to branch 3.0.1-release
in repository https://gitbox.apache.org/repos/asf/dubbo.git
commit 84d6bb74b3f876800aa85a83969d5040a8698292
Author: Gong Dewei <ky...@qq.com>
AuthorDate: Mon Jun 28 19:00:36 2021 +0800
Support generic call by reference without interface class locally (#8159)
---
.../apache/dubbo/config/ReferenceConfigBase.java | 6 +--
.../org/apache/dubbo/rpc/model/ConsumerModel.java | 11 +++-
.../org/apache/dubbo/config/ReferenceConfig.java | 2 +-
.../apache/dubbo/config/spring/ReferenceBean.java | 63 ++++++++++++----------
.../ReferenceAnnotationBeanPostProcessor.java | 18 ++-----
.../spring/schema/DubboBeanDefinitionParser.java | 20 +++----
.../javaconfig/JavaConfigReferenceBeanTest.java | 8 +--
.../config/spring/schema/GenericServiceTest.java | 38 +++++++++++--
.../META-INF/spring/dubbo-generic-consumer.xml | 7 ++-
.../src/test/resources/log4j.xml | 4 +-
10 files changed, 104 insertions(+), 73 deletions(-)
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java b/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java
index c3d2af7..2e6e719 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java
@@ -144,17 +144,17 @@ public abstract class ReferenceConfigBase<T> extends AbstractReferenceConfig {
}
/**
- * Get actual interface class of this reference.
+ * Get service interface class of this reference.
* The actual service type of remote provider.
* @return
*/
- public Class<?> getActualInterface() {
+ public Class<?> getServiceInterfaceClass() {
Class actualInterface = interfaceClass;
if (interfaceClass == GenericService.class) {
try {
actualInterface = Class.forName(interfaceName);
} catch (ClassNotFoundException e) {
- // ignore
+ return null;
}
}
return actualInterface;
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ConsumerModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ConsumerModel.java
index 34fe276..ce4ab6a 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ConsumerModel.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ConsumerModel.java
@@ -18,6 +18,7 @@ package org.apache.dubbo.rpc.model;
import org.apache.dubbo.common.BaseServiceMetadata;
import org.apache.dubbo.common.utils.Assert;
+import org.apache.dubbo.common.utils.ClassUtils;
import org.apache.dubbo.config.ReferenceConfigBase;
import java.lang.reflect.Method;
@@ -146,7 +147,12 @@ public class ConsumerModel {
public void initMethodModels() {
Class[] interfaceList = null;
if (proxyObject == null) {
- interfaceList = new Class[]{referenceConfig.getActualInterface()};
+ Class<?> serviceInterfaceClass = referenceConfig.getServiceInterfaceClass();
+ if (serviceInterfaceClass != null) {
+ interfaceList = new Class[]{serviceInterfaceClass};
+ } else {
+ interfaceList = new Class[0];
+ }
} else {
interfaceList = proxyObject.getClass().getInterfaces();
}
@@ -158,7 +164,8 @@ public class ConsumerModel {
}
public ClassLoader getClassLoader() {
- return serviceMetadata.getServiceType().getClassLoader();
+ Class<?> serviceType = serviceMetadata.getServiceType();
+ return serviceType != null ? serviceType.getClassLoader() : ClassUtils.getClassLoader();
}
/**
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
index 442713d..ee1a448 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
@@ -250,7 +250,7 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
//init serivceMetadata
initServiceMetadata(consumer);
- serviceMetadata.setServiceType(getActualInterface());
+ serviceMetadata.setServiceType(getServiceInterfaceClass());
// TODO, uncomment this line once service key is unified
serviceMetadata.setServiceKey(URL.buildKey(interfaceName, group, version));
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java
index f06caa3..212e05c 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java
@@ -18,8 +18,8 @@ package org.apache.dubbo.config.spring;
import org.apache.dubbo.common.utils.Assert;
import org.apache.dubbo.common.utils.ClassUtils;
+import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.ReferenceConfig;
-import org.apache.dubbo.config.ReferenceConfigBase;
import org.apache.dubbo.config.spring.reference.ReferenceBeanManager;
import org.apache.dubbo.config.spring.reference.ReferenceBeanSupport;
import org.apache.dubbo.config.spring.reference.ReferenceAttributes;
@@ -115,17 +115,10 @@ public class ReferenceBean<T> implements FactoryBean,
*/
private Class<?> interfaceClass;
- /**
- * Actual interface class of this reference.
- * The actual service type of remote provider.
- * see {@link ReferenceConfigBase#getActualInterface()}
- */
- private Class actualInterface;
-
/*
- * actual interface class name
+ * remote service interface class name
*/
- // Compatible with seata-1.4.0: io.seata.rm.tcc.remoting.parser.DubboRemotingParser#getServiceDesc()
+ // 'interfaceName' field for compatible with seata-1.4.0: io.seata.rm.tcc.remoting.parser.DubboRemotingParser#getServiceDesc()
private String interfaceName;
//from annotation attributes
@@ -214,7 +207,7 @@ public class ReferenceBean<T> implements FactoryBean,
Assert.notEmptyString(getId(), "The id of ReferenceBean cannot be empty");
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(getId());
this.interfaceClass = (Class<?>) beanDefinition.getAttribute(ReferenceAttributes.INTERFACE_CLASS);
- this.actualInterface = (Class) beanDefinition.getAttribute(ReferenceAttributes.ACTUAL_INTERFACE);
+ this.interfaceName = (String) beanDefinition.getAttribute(ReferenceAttributes.INTERFACE_NAME);
Assert.notNull(this.interfaceClass, "The interface class of ReferenceBean is not initialized");
if (beanDefinition.hasAttribute(Constants.REFERENCE_PROPS)) {
@@ -228,20 +221,15 @@ public class ReferenceBean<T> implements FactoryBean,
referenceProps = new LinkedHashMap<>();
}
ReferenceBeanSupport.convertReferenceProps(referenceProps, interfaceClass);
- if (this.actualInterface == null) {
- try {
- this.actualInterface = ClassUtils.forName((String) referenceProps.get(ReferenceAttributes.INTERFACE));
- } catch (ClassNotFoundException e) {
- throw new IllegalStateException(e.getMessage(), e);
- }
+ if (this.interfaceName == null) {
+ this.interfaceName = (String) referenceProps.get(ReferenceAttributes.INTERFACE);
}
} else {
// xml reference bean
propertyValues = beanDefinition.getPropertyValues();
}
}
- Assert.notNull(this.actualInterface, "The actual interface of ReferenceBean is not initialized");
- this.interfaceName = actualInterface.getName();
+ Assert.notNull(this.interfaceName, "The interface name of ReferenceBean is not initialized");
// this.sources = (List<Map<String, Object>>) beanDefinition.getAttribute(Constants.REFERENCE_SOURCES);
// Assert.notNull(this.sources, "The registration sources of this reference is empty");
@@ -267,22 +255,36 @@ public class ReferenceBean<T> implements FactoryBean,
this.id = id;
}
- /* Compatible with seata-1.4.0: io.seata.rm.tcc.remoting.parser.DubboRemotingParser#getServiceDesc() */
+
+ /**
+ * The interface of this ReferenceBean, for injection purpose
+ * @return
+ */
public Class<?> getInterfaceClass() {
+ // Compatible with seata-1.4.0: io.seata.rm.tcc.remoting.parser.DubboRemotingParser#getServiceDesc()
return interfaceClass;
}
- public Class getActualInterface() {
- return actualInterface;
+ /**
+ * The interface of remote service
+ */
+ public String getServiceInterface() {
+ return interfaceName;
}
- /* Compatible with seata-1.4.0: io.seata.rm.tcc.remoting.parser.DubboRemotingParser#getServiceDesc() */
+ /**
+ * The group of the service
+ */
public String getGroup() {
+ // Compatible with seata-1.4.0: io.seata.rm.tcc.remoting.parser.DubboRemotingParser#getServiceDesc()
return referenceConfig.getGroup();
}
- /* Compatible with seata-1.4.0: io.seata.rm.tcc.remoting.parser.DubboRemotingParser#getServiceDesc() */
+ /**
+ * The version of the service
+ */
public String getVersion() {
+ // Compatible with seata-1.4.0: io.seata.rm.tcc.remoting.parser.DubboRemotingParser#getServiceDesc()
return referenceConfig.getVersion();
}
@@ -316,14 +318,19 @@ public class ReferenceBean<T> implements FactoryBean,
//see also: org.apache.dubbo.rpc.proxy.AbstractProxyFactory.getProxy(org.apache.dubbo.rpc.Invoker<T>, boolean)
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTargetSource(new DubboReferenceLazyInitTargetSource());
- proxyFactory.addInterface(getInterfaceClass());
+ proxyFactory.addInterface(interfaceClass);
Class<?>[] internalInterfaces = AbstractProxyFactory.getInternalInterfaces();
for (Class<?> anInterface : internalInterfaces) {
proxyFactory.addInterface(anInterface);
}
- if (actualInterface != interfaceClass){
- //add actual interface
- proxyFactory.addInterface(actualInterface);
+ if (!StringUtils.isEquals(interfaceClass.getName(), interfaceName)) {
+ //add service interface
+ try {
+ Class<?> serviceInterface = ClassUtils.forName(interfaceName, beanClassLoader);
+ proxyFactory.addInterface(serviceInterface);
+ } catch (ClassNotFoundException e) {
+ // generic call maybe without service interface class locally
+ }
}
this.lazyProxy = proxyFactory.getProxy(this.beanClassLoader);
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 2f4166f..0c4d8b4 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
@@ -237,23 +237,17 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean
}
Class interfaceClass = beanClass;
- Class actualInterface = null;
- try {
- actualInterface = ClassUtils.forName(interfaceName);
- } catch (ClassNotFoundException e) {
- throw new IllegalStateException(e.getMessage(), e);
- }
// set attribute instead of property values
beanDefinition.setAttribute(Constants.REFERENCE_PROPS, attributes);
beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_CLASS, interfaceClass);
- beanDefinition.setAttribute(ReferenceAttributes.ACTUAL_INTERFACE, actualInterface);
+ beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_NAME, interfaceName);
} else {
// raw reference bean
// the ReferenceBean is not yet initialized
beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_CLASS, beanClass);
if (beanClass != GenericService.class) {
- beanDefinition.setAttribute(ReferenceAttributes.ACTUAL_INTERFACE, beanClass);
+ beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_NAME, beanClass.getName());
}
}
@@ -442,12 +436,6 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean
}
Class interfaceClass = injectedType;
- Class actualInterface = null;
- try {
- actualInterface = ClassUtils.forName(interfaceName);
- } catch (ClassNotFoundException e) {
- throw new IllegalStateException(e.getMessage(), e);
- }
// TODO Only register one reference bean for same (group, interface, version)
@@ -459,7 +447,7 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean
// set attribute instead of property values
beanDefinition.setAttribute(Constants.REFERENCE_PROPS, attributes);
beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_CLASS, interfaceClass);
- beanDefinition.setAttribute(ReferenceAttributes.ACTUAL_INTERFACE, actualInterface);
+ beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_NAME, interfaceName);
// create decorated definition for reference bean, Avoid being instantiated when getting the beanType of ReferenceBean
// see org.springframework.beans.factory.support.AbstractBeanFactory#getTypeForFactoryBean()
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java
index 305cfd4..c15512a 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java
@@ -18,7 +18,6 @@ package org.apache.dubbo.config.spring.schema;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.ClassUtils;
import org.apache.dubbo.common.utils.ReflectUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.AbstractServiceConfig;
@@ -32,6 +31,7 @@ import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.spring.Constants;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.config.spring.ServiceBean;
+import org.apache.dubbo.config.spring.reference.ReferenceAttributes;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
@@ -246,27 +246,21 @@ public class DubboBeanDefinitionParser implements BeanDefinitionParser {
private static void configReferenceBean(Element element, ParserContext parserContext, RootBeanDefinition beanDefinition, BeanDefinition consumerDefinition) {
// process interface class
- String interfaceName = resolveAttribute(element, "interface", parserContext);
- String generic = resolveAttribute(element, "generic", parserContext);
+ String interfaceName = resolveAttribute(element, ReferenceAttributes.INTERFACE, parserContext);
+ String generic = resolveAttribute(element, ReferenceAttributes.GENERIC, parserContext);
if (StringUtils.isBlank(generic) && consumerDefinition != null) {
// get generic from consumerConfig
- generic = (String) consumerDefinition.getPropertyValues().get("generic");
+ generic = (String) consumerDefinition.getPropertyValues().get(ReferenceAttributes.GENERIC);
}
if (generic != null) {
Environment environment = parserContext.getReaderContext().getEnvironment();
generic = environment.resolvePlaceholders(generic);
- beanDefinition.getPropertyValues().add("generic", generic);
+ beanDefinition.getPropertyValues().add(ReferenceAttributes.GENERIC, generic);
}
+ beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_NAME, interfaceName);
Class interfaceClass = ReferenceConfig.determineInterfaceClass(generic, interfaceName);
- Class actualInterface = null;
- try {
- actualInterface = ClassUtils.forName(interfaceName);
- } catch (ClassNotFoundException e) {
- throw new IllegalStateException(e.getMessage(), e);
- }
- beanDefinition.setAttribute("interfaceClass", interfaceClass);
- beanDefinition.setAttribute("actualInterface", actualInterface);
+ beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_CLASS, interfaceClass);
// TODO Only register one reference bean for same (group, interface, version)
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java
index 37d70f2..e0b2428 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java
@@ -71,12 +71,12 @@ public class JavaConfigReferenceBeanTest {
ReferenceBean referenceBean = referenceBeanMap.get("&helloService");
Assertions.assertEquals("demo", referenceBean.getGroup());
Assertions.assertEquals(HelloService.class, referenceBean.getInterfaceClass());
- Assertions.assertEquals(HelloService.class, referenceBean.getActualInterface());
+ Assertions.assertEquals(HelloService.class.getName(), referenceBean.getServiceInterface());
ReferenceBean genericHelloServiceReferenceBean = referenceBeanMap.get("&genericHelloService");
Assertions.assertEquals("demo", genericHelloServiceReferenceBean.getGroup());
Assertions.assertEquals(GenericService.class, genericHelloServiceReferenceBean.getInterfaceClass());
- Assertions.assertEquals(HelloService.class, genericHelloServiceReferenceBean.getActualInterface());
+ Assertions.assertEquals(HelloService.class.getName(), genericHelloServiceReferenceBean.getServiceInterface());
context.close();
Assertions.assertEquals(1, SpringExtensionFactory.getContexts().size());
@@ -101,12 +101,12 @@ public class JavaConfigReferenceBeanTest {
Assertions.assertEquals(3, referenceBeanMap.size());
ReferenceBean referenceBean = referenceBeanMap.get("&helloService");
Assertions.assertEquals(HelloService.class, referenceBean.getInterfaceClass());
- Assertions.assertEquals(HelloService.class, referenceBean.getActualInterface());
+ Assertions.assertEquals(HelloService.class.getName(), referenceBean.getServiceInterface());
ReferenceBean genericHelloServiceReferenceBean = referenceBeanMap.get("&genericHelloService");
Assertions.assertEquals("demo", genericHelloServiceReferenceBean.getGroup());
Assertions.assertEquals(GenericService.class, genericHelloServiceReferenceBean.getInterfaceClass());
- Assertions.assertEquals(HelloService.class, genericHelloServiceReferenceBean.getActualInterface());
+ Assertions.assertEquals(HelloService.class.getName(), genericHelloServiceReferenceBean.getServiceInterface());
context.close();
Assertions.assertEquals(1, SpringExtensionFactory.getContexts().size());
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/GenericServiceTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/GenericServiceTest.java
index de4ab91..105bbdf 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/GenericServiceTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/GenericServiceTest.java
@@ -16,10 +16,17 @@
*/
package org.apache.dubbo.config.spring.schema;
+import org.apache.dubbo.common.utils.ClassUtils;
+import org.apache.dubbo.config.ReferenceConfigBase;
+import org.apache.dubbo.config.ServiceConfigBase;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
-import org.apache.dubbo.config.spring.ReferenceBean;
+import org.apache.dubbo.config.context.ConfigManager;
import org.apache.dubbo.config.spring.ServiceBean;
+import org.apache.dubbo.config.spring.ZooKeeperServer;
+import org.apache.dubbo.config.spring.api.DemoService;
+import org.apache.dubbo.rpc.service.GenericService;
import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -41,6 +48,7 @@ public class GenericServiceTest {
@BeforeAll
public static void setUp() {
+ ZooKeeperServer.start();
DubboBootstrap.reset();
}
@@ -51,15 +59,37 @@ public class GenericServiceTest {
@Autowired
@Qualifier("demoServiceRef")
- private ReferenceBean referenceBean;
+ private GenericService demoServiceRef;
+
+ @Autowired
+ @Qualifier("genericServiceWithoutInterfaceRef")
+ private GenericService genericServiceWithoutInterfaceRef;
@Autowired
@Qualifier("demoService")
private ServiceBean serviceBean;
@Test
- public void testBeanDefinitionParser() {
- assertNotNull(referenceBean);
+ public void testGeneric() {
+ assertNotNull(demoServiceRef);
assertNotNull(serviceBean);
+
+ ConfigManager configManager = DubboBootstrap.getInstance().getConfigManager();
+ ServiceConfigBase<Object> serviceConfig = configManager.getService("demoService");
+ Assertions.assertEquals(DemoService.class.getName(), serviceConfig.getInterface());
+ Assertions.assertEquals(true, serviceConfig.isExported());
+
+ Object result = demoServiceRef.$invoke("sayHello", new String[]{"java.lang.String"}, new Object[]{"dubbo"});
+ Assertions.assertEquals("Welcome dubbo", result);
+
+
+ // Test generic service without interface class locally
+ result = genericServiceWithoutInterfaceRef.$invoke("sayHello", new String[]{"java.lang.String"}, new Object[]{"generic"});
+ Assertions.assertEquals("Welcome generic", result);
+
+ ReferenceConfigBase<Object> reference = configManager.getReference("genericServiceWithoutInterfaceRef");
+ Assertions.assertNull(reference.getServiceInterfaceClass());
+ Assertions.assertThrows(ClassNotFoundException.class, () -> ClassUtils.forName(reference.getInterface()));
+
}
}
diff --git a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/spring/dubbo-generic-consumer.xml b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/spring/dubbo-generic-consumer.xml
index 72bf442..a103e4f 100644
--- a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/spring/dubbo-generic-consumer.xml
+++ b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/spring/dubbo-generic-consumer.xml
@@ -25,7 +25,7 @@
<dubbo:application name="dubbo-generic-consumer"/>
<!-- 连接注册中心配置 -->
- <dubbo:registry address="N/A"/>
+ <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<dubbo:reference id="demoServiceRef" interface="org.apache.dubbo.config.spring.api.DemoService" generic="true" init="false"/>
@@ -33,4 +33,9 @@
<dubbo:service id="demoService" interface="org.apache.dubbo.config.spring.api.DemoService" generic="true"
ref="genericService"/>
+
+ <!-- generic service without interface class -->
+ <dubbo:reference id="genericServiceWithoutInterfaceRef" interface="org.apache.dubbo.config.spring.api.LocalMissService" generic="true" init="false"/>
+ <dubbo:service id="genericServiceWithoutInterface" interface="org.apache.dubbo.config.spring.api.LocalMissService" generic="true"
+ ref="genericService"/>
</beans>
diff --git a/dubbo-config/dubbo-config-spring/src/test/resources/log4j.xml b/dubbo-config/dubbo-config-spring/src/test/resources/log4j.xml
index 24e59e1..5d27202 100644
--- a/dubbo-config/dubbo-config-spring/src/test/resources/log4j.xml
+++ b/dubbo-config/dubbo-config-spring/src/test/resources/log4j.xml
@@ -23,7 +23,7 @@
</layout>
</appender>
- <logger name="org.apache.dubbo.config.spring" additivity="false">
+ <logger name="org.apache.dubbo.config" additivity="false">
<level value="DEBUG"/>
<appender-ref ref="CONSOLE"/>
</logger>
@@ -32,4 +32,4 @@
<level value="INFO"/>
<appender-ref ref="CONSOLE"/>
</root>
-</log4j:configuration>
\ No newline at end of file
+</log4j:configuration>