INT-981 Added MethodFilter to be invoked by ReflectionUtils.doWithMethods(..)
This commit is contained in:
@@ -20,6 +20,7 @@ import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -30,7 +31,6 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.context.expression.MapAccessor;
|
||||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
@@ -56,9 +56,11 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.ReflectionUtils.MethodCallback;
|
||||
import org.springframework.util.ReflectionUtils.MethodFilter;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0
|
||||
*/
|
||||
public class MethodInvokingMessageProcessor implements MessageProcessor {
|
||||
@@ -142,7 +144,7 @@ public class MethodInvokingMessageProcessor implements MessageProcessor {
|
||||
new FixedHandlerMethodFilter((Method) method), targetType));
|
||||
}
|
||||
else if (method == null || method instanceof String) {
|
||||
context.getMethodResolvers().add(new FilteringReflectiveMethodResolver(
|
||||
context.getMethodResolvers().add(new FilteringReflectiveMethodResolver(
|
||||
new HandlerMethodFilter(annotationType, (String) method, this.requiresReply), targetType));
|
||||
}
|
||||
context.addPropertyAccessor(new MapAccessor());
|
||||
@@ -192,7 +194,8 @@ public class MethodInvokingMessageProcessor implements MessageProcessor {
|
||||
final Map<Class<?>, HandlerMethod> candidateMethods = new HashMap<Class<?>, HandlerMethod>();
|
||||
final Map<Class<?>, HandlerMethod> fallbackMethods = new HashMap<Class<?>, HandlerMethod>();
|
||||
final AtomicReference<Class<?>> ambiguousFallbackType = new AtomicReference<Class<?>>();
|
||||
Class<?> targetClass = this.getTargetClass(targetObject);
|
||||
final Class<?> targetClass = this.getTargetClass(targetObject);
|
||||
MethodFilter methodFilter = new UniqueMethodFilter(targetClass);
|
||||
ReflectionUtils.doWithMethods(targetClass, new MethodCallback() {
|
||||
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
|
||||
boolean matchesAnnotation = false;
|
||||
@@ -240,7 +243,7 @@ public class MethodInvokingMessageProcessor implements MessageProcessor {
|
||||
fallbackMethods.put(targetParameterType, handlerMethod);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, methodFilter);
|
||||
if (!candidateMethods.isEmpty()) {
|
||||
return candidateMethods;
|
||||
}
|
||||
@@ -445,5 +448,21 @@ public class MethodInvokingMessageProcessor implements MessageProcessor {
|
||||
this.targetParameterType = targetParameterType;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0
|
||||
*/
|
||||
private class UniqueMethodFilter implements MethodFilter {
|
||||
private List<Method> uniqueMethods = new ArrayList<Method>();
|
||||
|
||||
public UniqueMethodFilter(Class<?> targetClass){
|
||||
ArrayList<Method> allMethods = new ArrayList<Method>(Arrays.asList(targetClass.getMethods()));
|
||||
for (Method method : allMethods) {
|
||||
uniqueMethods.add(org.springframework.util.ClassUtils.getMostSpecificMethod(method, targetClass));
|
||||
}
|
||||
}
|
||||
public boolean matches(Method method) {
|
||||
return uniqueMethods.contains(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,9 +38,82 @@ import org.springframework.integration.message.StringMessage;
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Marius Bogoevici
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
public class MethodInvokingMessageProcessorTests {
|
||||
|
||||
@Test
|
||||
public void testHandlerInheritanceMethodImplInSuper() {
|
||||
class A{
|
||||
public Message<String> myMethod(final Message<String> msg){
|
||||
return MessageBuilder.fromMessage(msg).setHeader("A", "A").build();
|
||||
}
|
||||
}
|
||||
class B extends A{}
|
||||
class C extends B{}
|
||||
MethodInvokingMessageProcessor processor = new MethodInvokingMessageProcessor(
|
||||
new B(), "myMethod");
|
||||
Message message = (Message) processor.processMessage(new StringMessage(""));
|
||||
assertEquals("A", message.getHeaders().get("A"));
|
||||
}
|
||||
@Test
|
||||
public void testHandlerInheritanceMethodImplInLatestSuper() {
|
||||
class A{
|
||||
public Message<String> myMethod(Message<String> msg){
|
||||
return MessageBuilder.fromMessage(msg).setHeader("A", "A").build();
|
||||
}
|
||||
}
|
||||
class B extends A{
|
||||
public Message<String> myMethod(Message<String> msg){
|
||||
return MessageBuilder.fromMessage(msg).setHeader("B", "B").build();
|
||||
}
|
||||
}
|
||||
class C extends B{}
|
||||
MethodInvokingMessageProcessor processor = new MethodInvokingMessageProcessor(
|
||||
new B(), "myMethod");
|
||||
Message message = (Message) processor.processMessage(new StringMessage(""));
|
||||
assertEquals("B", message.getHeaders().get("B"));
|
||||
}
|
||||
|
||||
public void testHandlerInheritanceMethodImplInSubClass() {
|
||||
class A{
|
||||
public Message<String> myMethod(Message<String> msg){
|
||||
return MessageBuilder.fromMessage(msg).setHeader("A", "A").build();
|
||||
}
|
||||
}
|
||||
class B extends A{
|
||||
public Message<String> myMethod(Message<String> msg){
|
||||
return MessageBuilder.fromMessage(msg).setHeader("B", "B").build();
|
||||
}
|
||||
}
|
||||
class C extends B{
|
||||
public Message<String> myMethod(Message<String> msg){
|
||||
return MessageBuilder.fromMessage(msg).setHeader("C", "C").build();
|
||||
}
|
||||
}
|
||||
MethodInvokingMessageProcessor processor = new MethodInvokingMessageProcessor(
|
||||
new C(), "myMethod");
|
||||
Message message = (Message) processor.processMessage(new StringMessage(""));
|
||||
assertEquals("C", message.getHeaders().get("C"));
|
||||
}
|
||||
public void testHandlerInheritanceMethodImplInSubClassAndSuper() {
|
||||
class A{
|
||||
public Message<String> myMethod(Message<String> msg){
|
||||
return MessageBuilder.fromMessage(msg).setHeader("A", "A").build();
|
||||
}
|
||||
}
|
||||
class B extends A{}
|
||||
class C extends B{
|
||||
public Message<String> myMethod(Message<String> msg){
|
||||
return MessageBuilder.fromMessage(msg).setHeader("C", "C").build();
|
||||
}
|
||||
}
|
||||
MethodInvokingMessageProcessor processor = new MethodInvokingMessageProcessor(
|
||||
new C(), "myMethod");
|
||||
Message message = (Message) processor.processMessage(new StringMessage(""));
|
||||
assertEquals("C", message.getHeaders().get("C"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void payloadAsMethodParameterAndObjectAsReturnValue() {
|
||||
MethodInvokingMessageProcessor processor = new MethodInvokingMessageProcessor(
|
||||
@@ -198,6 +271,7 @@ public class MethodInvokingMessageProcessorTests {
|
||||
assertEquals(String.class, bean.lastArg.getClass());
|
||||
assertEquals("true", bean.lastArg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
||||
Reference in New Issue
Block a user