INT-4367: Fix MessagingMethodInvHelper for CGLIB

JIRA: https://jira.spring.io/browse/INT-4367

When CGLIB proxy is used for messaging POJO invocation,
the `InvocableHandlerMethod` doesn't recognize method parameter
annotations and therefore the logic is wrong at runtime or just
rejected during method processing

* Use `AopUtils.selectInvocableMethod()` to select the proper method to
call according the provided proxy type
This commit is contained in:
Artem Bilan
2017-12-12 19:04:16 -05:00
committed by Gary Russell
parent 2f450f7cde
commit 21bf69b7f8
2 changed files with 40 additions and 1 deletions

View File

@@ -702,7 +702,8 @@ public class MessagingMethodInvokerHelper<T> extends AbstractExpressionEvaluator
}
HandlerMethod handlerMethod1;
try {
method1 = org.springframework.util.ClassUtils.getMostSpecificMethod(method1, targetObject.getClass());
method1 = AopUtils.selectInvocableMethod(method1,
org.springframework.util.ClassUtils.getUserClass(targetObject));
InvocableHandlerMethod invocableHandlerMethod =
this.messageHandlerMethodFactory.createInvocableHandlerMethod(targetObject, method1);
handlerMethod1 = new HandlerMethod(invocableHandlerMethod, this.canProcessMessageList);

View File

@@ -37,6 +37,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
@@ -74,6 +75,7 @@ import org.springframework.messaging.MessageHandlingException;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.util.StopWatch;
@@ -809,6 +811,42 @@ public class MethodInvokingMessageProcessorTests {
assertTrue(adviceCalled.get());
}
@Test
public void testProxyAndHeaderAnnotation() {
final AtomicReference<Object> payloadReference = new AtomicReference<>();
final AtomicReference<UUID> idReference = new AtomicReference<>();
class MyHandler {
public void handle(@Header(MessageHeaders.ID) UUID id, @Payload Object payload) {
idReference.set(id);
payloadReference.set(payload);
}
}
MyHandler service = new MyHandler();
final AtomicBoolean adviceCalled = new AtomicBoolean();
ProxyFactory proxyFactory = new ProxyFactory(service);
proxyFactory.addAdvice((MethodInterceptor) i -> {
adviceCalled.set(true);
return i.proceed();
});
service = (MyHandler) proxyFactory.getProxy(getClass().getClassLoader());
GenericMessage<String> testMessage = new GenericMessage<>("foo");
MethodInvokingMessageProcessor processor = new MethodInvokingMessageProcessor(service, "handle");
processor.processMessage(testMessage);
assertEquals(testMessage.getPayload(), payloadReference.get());
assertEquals(testMessage.getHeaders().getId(), idReference.get());
assertTrue(adviceCalled.get());
}
@Test
public void testUseSpelInvoker() throws Exception {
UseSpelInvokerBean bean = new UseSpelInvokerBean();