From 026046fb157fe4390cc6c97f853c380b85614e42 Mon Sep 17 00:00:00 2001 From: mercyblitz Date: Tue, 2 Apr 2019 17:43:44 +0800 Subject: [PATCH] Polish spring-cloud-incubator/spring-cloud-alibaba#500 : dubbo failed to transfer object using Fegin mode --- .../openfeign/DubboInvocationHandler.java | 19 ++++++++++++++++++- .../openfeign/TargeterBeanPostProcessor.java | 2 +- .../openfeign/TargeterInvocationHandler.java | 9 +++++++-- .../DubboSpringCloudConsumerBootstrap.java | 2 +- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/DubboInvocationHandler.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/DubboInvocationHandler.java index ab4d18fa..01d038fb 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/DubboInvocationHandler.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/DubboInvocationHandler.java @@ -17,14 +17,18 @@ package org.springframework.cloud.alibaba.dubbo.openfeign; import org.apache.dubbo.rpc.service.GenericService; + import org.springframework.cloud.alibaba.dubbo.metadata.RestMethodMetadata; import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContext; import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContextFactory; +import org.springframework.util.ClassUtils; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.Map; +import static org.apache.dubbo.common.utils.PojoUtils.realize; + /** * Dubbo {@link GenericService} for {@link InvocationHandler} * @@ -38,11 +42,15 @@ public class DubboInvocationHandler implements InvocationHandler { private final DubboGenericServiceExecutionContextFactory contextFactory; + private final ClassLoader classLoader; + public DubboInvocationHandler(Map feignMethodMetadataMap, InvocationHandler defaultInvocationHandler, + ClassLoader classLoader, DubboGenericServiceExecutionContextFactory contextFactory) { this.feignMethodMetadataMap = feignMethodMetadataMap; this.defaultInvocationHandler = defaultInvocationHandler; + this.classLoader = classLoader; this.contextFactory = contextFactory; } @@ -65,6 +73,15 @@ public class DubboInvocationHandler implements InvocationHandler { String[] parameterTypes = context.getParameterTypes(); Object[] parameters = context.getParameters(); - return dubboGenericService.$invoke(methodName, parameterTypes, parameters); + Object result = dubboGenericService.$invoke(methodName, parameterTypes, parameters); + + Class returnType = getReturnType(dubboRestMethodMetadata); + + return realize(result, returnType); + } + + private Class getReturnType(RestMethodMetadata dubboRestMethodMetadata) { + String returnType = dubboRestMethodMetadata.getReturnType(); + return ClassUtils.resolveClassName(returnType, classLoader); } } diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/TargeterBeanPostProcessor.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/TargeterBeanPostProcessor.java index 331e7a00..0419a157 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/TargeterBeanPostProcessor.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/TargeterBeanPostProcessor.java @@ -69,7 +69,7 @@ public class TargeterBeanPostProcessor implements BeanPostProcessor, BeanClassLo Class targetClass = resolveClassName(TARGETER_CLASS_NAME, classLoader); if (targetClass.isAssignableFrom(beanClass)) { return newProxyInstance(classLoader, new Class[]{targetClass}, - new TargeterInvocationHandler(bean, environment, dubboServiceMetadataRepository, + new TargeterInvocationHandler(bean, environment, classLoader, dubboServiceMetadataRepository, dubboGenericServiceFactory, contextFactory)); } } diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/TargeterInvocationHandler.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/TargeterInvocationHandler.java index fa93bb27..6e9ca7f4 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/TargeterInvocationHandler.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/TargeterInvocationHandler.java @@ -57,17 +57,22 @@ class TargeterInvocationHandler implements InvocationHandler { private final Environment environment; + private final ClassLoader classLoader; + private final DubboServiceMetadataRepository repository; private final DubboGenericServiceFactory dubboGenericServiceFactory; private final DubboGenericServiceExecutionContextFactory contextFactory; - TargeterInvocationHandler(Object bean, Environment environment, DubboServiceMetadataRepository repository, + TargeterInvocationHandler(Object bean, Environment environment, + ClassLoader classLoader, + DubboServiceMetadataRepository repository, DubboGenericServiceFactory dubboGenericServiceFactory, DubboGenericServiceExecutionContextFactory contextFactory) { this.bean = bean; this.environment = environment; + this.classLoader = classLoader; this.repository = repository; this.dubboGenericServiceFactory = dubboGenericServiceFactory; this.contextFactory = contextFactory; @@ -134,7 +139,7 @@ class TargeterInvocationHandler implements InvocationHandler { InvocationHandler defaultFeignClientInvocationHandler = Proxy.getInvocationHandler(defaultFeignClientProxy); DubboInvocationHandler dubboInvocationHandler = new DubboInvocationHandler(feignMethodMetadataMap, - defaultFeignClientInvocationHandler, contextFactory); + defaultFeignClientInvocationHandler, classLoader, contextFactory); return dubboInvocationHandler; } diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudConsumerBootstrap.java b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudConsumerBootstrap.java index 2e389ce2..45484000 100644 --- a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudConsumerBootstrap.java +++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudConsumerBootstrap.java @@ -192,7 +192,7 @@ public class DubboSpringCloudConsumerBootstrap { // Dubbo Service call System.out.println(restService.requestBodyMap(data, "Hello,World")); // Spring Cloud Open Feign REST Call (Dubbo Transported) -// System.out.println(dubboFeignRestService.requestBody("Hello,World", data)); + System.out.println(dubboFeignRestService.requestBody("Hello,World", data)); // Spring Cloud Open Feign REST Call System.out.println(feignRestService.requestBody("Hello,World", data));