Feature/20231114 dubbo 3.2 rest proxy double service method (#13357)

* for proxy service method repeat check

* for proxy service method repeat check

* fix code format

* fix code format

* fix code format

* fix code format

* fix code format

* fix code format

* fix code format

* fix code format

* fix code format

---------

Co-authored-by: huazhongming <crazyhzm@gmail.com>
This commit is contained in:
suncairong163 2023-12-01 15:28:05 +08:00 committed by GitHub
parent d552cfca51
commit 6e9f337098
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 5 deletions

View File

@ -29,6 +29,8 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
@ -207,20 +209,41 @@ public abstract class AbstractServiceRestMetadataResolver implements ServiceRest
sort(declaredServiceMethods, MethodComparator.INSTANCE);
sort(serviceMethods, MethodComparator.INSTANCE);
// prevent from repeat method (impl proxy) & leaving out method(interface proxy)
HashSet<String> methodComparators = new HashSet<>();
// TODO Map key: method desc & value: Set<Method> for accelerate loop speed
for (Method declaredServiceMethod : declaredServiceMethods) {
for (Method serviceMethod : serviceMethods) {
if (overrides(serviceMethod, declaredServiceMethod)) {
serviceMethodsMap.put(serviceMethod, declaredServiceMethod);
// override method count > 1
// // once method match ,break for decrease loop times
// break;
if (!overrides(serviceMethod, declaredServiceMethod)) {
continue;
}
String methodDesc = getMethodDesc(serviceMethod);
if (!methodComparators.add(methodDesc)) {
continue;
}
serviceMethodsMap.put(serviceMethod, declaredServiceMethod);
}
}
// make them to be read-only
return unmodifiableMap(serviceMethodsMap);
}
/**
* For simple method desc
*
* @param serviceMethod
* @return
*/
private String getMethodDesc(Method serviceMethod) {
return serviceMethod.getName() + Arrays.toString(serviceMethod.getParameterTypes());
}
private void putServiceMethodToMap(Map<Method, Method> serviceMethodsMap, List<Method> declaredServiceMethods) {
declaredServiceMethods.stream().forEach(method -> {

View File

@ -47,6 +47,9 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.framework.AopProxy;
import org.springframework.aop.framework.ProxyCreatorSupport;
import org.springframework.util.LinkedMultiValueMap;
import static org.apache.dubbo.remoting.Constants.SERVER_KEY;
@ -393,6 +396,35 @@ public class SpringMvcRestProtocolTest {
exporter.unexport();
}
@Test
void testProxyDoubleCheck() {
ProxyCreatorSupport proxyCreatorSupport = new ProxyCreatorSupport();
AdvisedSupport advisedSupport = new AdvisedSupport();
advisedSupport.setTarget(getServerImpl());
AopProxy aopProxy = proxyCreatorSupport.getAopProxyFactory().createAopProxy(advisedSupport);
Object proxy = aopProxy.getProxy();
SpringRestDemoService server = (SpringRestDemoService) proxy;
URL nettyUrl = this.registerProvider(exportUrl, server, SpringRestDemoService.class);
Exporter<SpringRestDemoService> exporter = getExport(nettyUrl, server);
SpringRestDemoService demoService = this.proxy.getProxy(protocol.refer(SpringRestDemoService.class, nettyUrl));
Integer result = demoService.primitiveInt(1, 2);
Long resultLong = demoService.primitiveLong(1, 2l);
long resultByte = demoService.primitiveByte((byte) 1, 2l);
long resultShort = demoService.primitiveShort((short) 1, 2l, 1);
assertThat(result, is(3));
assertThat(resultShort, is(3l));
assertThat(resultLong, is(3l));
assertThat(resultByte, is(3l));
exporter.unexport();
}
public static class TestExceptionMapper implements ExceptionHandler<RuntimeException> {
@Override