diff --git a/org.springframework.integration/.classpath b/org.springframework.integration/.classpath
index 34c01dfac1..8cfdd6f039 100644
--- a/org.springframework.integration/.classpath
+++ b/org.springframework.integration/.classpath
@@ -4,6 +4,7 @@
+
diff --git a/org.springframework.integration/ivy.xml b/org.springframework.integration/ivy.xml
index 144dc2d43e..17ed703c40 100644
--- a/org.springframework.integration/ivy.xml
+++ b/org.springframework.integration/ivy.xml
@@ -20,6 +20,7 @@
+
diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/aggregator/MethodInvokingAggregator.java b/org.springframework.integration/src/main/java/org/springframework/integration/aggregator/MethodInvokingAggregator.java
index 289bb52f58..39cf23e45a 100644
--- a/org.springframework.integration/src/main/java/org/springframework/integration/aggregator/MethodInvokingAggregator.java
+++ b/org.springframework.integration/src/main/java/org/springframework/integration/aggregator/MethodInvokingAggregator.java
@@ -52,7 +52,7 @@ public class MethodInvokingAggregator extends AbstractMessageAggregator {
public MethodInvokingAggregator(Object object) {
Assert.notNull(object, "object must not be null");
- Method method = this.methodResolver.findMethod(object.getClass());
+ Method method = this.methodResolver.findMethod(object);
Assert.notNull(method, "unable to resolve Aggregator method on target class ["
+ object.getClass() + "]");
this.methodInvoker = new MessageListMethodAdapter(object, method);
diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/ServiceActivatorEndpoint.java b/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/ServiceActivatorEndpoint.java
index 0f01982e08..64903ccb69 100644
--- a/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/ServiceActivatorEndpoint.java
+++ b/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/ServiceActivatorEndpoint.java
@@ -45,7 +45,7 @@ public class ServiceActivatorEndpoint extends AbstractReplyProducingMessageConsu
public ServiceActivatorEndpoint(final Object object) {
Assert.notNull(object, "object must not be null");
- Method method = this.methodResolver.findMethod(object.getClass());
+ Method method = this.methodResolver.findMethod(object);
Assert.notNull(method, "unable to resolve ServiceActivator method on target class ["
+ object.getClass() + "]");
this.invoker = new MessageMappingMethodInvoker(object, method);
diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/splitter/MethodInvokingSplitter.java b/org.springframework.integration/src/main/java/org/springframework/integration/splitter/MethodInvokingSplitter.java
index e873e380e2..2a610d91a3 100644
--- a/org.springframework.integration/src/main/java/org/springframework/integration/splitter/MethodInvokingSplitter.java
+++ b/org.springframework.integration/src/main/java/org/springframework/integration/splitter/MethodInvokingSplitter.java
@@ -52,7 +52,7 @@ public class MethodInvokingSplitter extends AbstractMessageSplitter implements I
public MethodInvokingSplitter(Object object) {
Assert.notNull(object, "object must not be null");
- Method method = this.methodResolver.findMethod(object.getClass());
+ Method method = this.methodResolver.findMethod(object);
Assert.notNull(method, "unable to resolve Splitter method on target class ["
+ object.getClass() + "]");
this.invoker = new MessageMappingMethodInvoker(object, method);
diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/util/AnnotationMethodResolver.java b/org.springframework.integration/src/main/java/org/springframework/integration/util/AnnotationMethodResolver.java
index 19c4a8cb69..85e777c1d1 100644
--- a/org.springframework.integration/src/main/java/org/springframework/integration/util/AnnotationMethodResolver.java
+++ b/org.springframework.integration/src/main/java/org/springframework/integration/util/AnnotationMethodResolver.java
@@ -22,6 +22,7 @@ import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicReference;
+import org.springframework.aop.support.AopUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -50,6 +51,29 @@ public class AnnotationMethodResolver implements MethodResolver {
}
+ /**
+ * Find a single Method on the Class of the given candidate object
+ * that contains the annotation type for which this resolver is searching.
+ *
+ * @param candidate the instance whose Class will be checked for the
+ * annotation
+ * @param annotationType the Method-level annotation type
+ *
+ * @return a single matching Method instance or null if the
+ * candidate's Class contains no Methods with the specified annotation
+ *
+ * @throws IllegalArgumentException if more than one Method has the
+ * specified annotation
+ */
+ public Method findMethod(Object candidate) {
+ Assert.notNull(candidate, "candidate object must not be null");
+ Class> targetClass = AopUtils.getTargetClass(candidate);
+ if (targetClass == null) {
+ targetClass = candidate.getClass();
+ }
+ return this.findMethod(targetClass);
+ }
+
/**
* Find a single Method on the given Class that contains the
* annotation type for which this resolver is searching.
@@ -64,6 +88,7 @@ public class AnnotationMethodResolver implements MethodResolver {
* specified annotation
*/
public Method findMethod(final Class> clazz) {
+ Assert.notNull(clazz, "class must not be null");
final AtomicReference annotatedMethod = new AtomicReference();
ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/util/DefaultMethodResolver.java b/org.springframework.integration/src/main/java/org/springframework/integration/util/DefaultMethodResolver.java
index ed0c953021..67cd71e173 100644
--- a/org.springframework.integration/src/main/java/org/springframework/integration/util/DefaultMethodResolver.java
+++ b/org.springframework.integration/src/main/java/org/springframework/integration/util/DefaultMethodResolver.java
@@ -19,6 +19,7 @@ package org.springframework.integration.util;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
+import org.springframework.aop.support.AopUtils;
import org.springframework.util.Assert;
/**
@@ -43,8 +44,16 @@ public class DefaultMethodResolver implements MethodResolver {
}
+ public Method findMethod(Object candidate) {
+ Assert.notNull(candidate, "candidate object must not be null");
+ Class> targetClass = AopUtils.getTargetClass(candidate);
+ if (targetClass == null) {
+ targetClass = candidate.getClass();
+ }
+ return this.findMethod(targetClass);
+ }
+
public Method findMethod(Class> clazz) {
- Assert.notNull(clazz, "Class must not be null");
if (this.annotationMethodResolver != null) {
Method method = this.annotationMethodResolver.findMethod(clazz);
if (method != null) {
diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/util/MethodResolver.java b/org.springframework.integration/src/main/java/org/springframework/integration/util/MethodResolver.java
index ddbd4024da..84523cbedb 100644
--- a/org.springframework.integration/src/main/java/org/springframework/integration/util/MethodResolver.java
+++ b/org.springframework.integration/src/main/java/org/springframework/integration/util/MethodResolver.java
@@ -26,10 +26,25 @@ import java.lang.reflect.Method;
public interface MethodResolver {
/**
- * Find a single Method on the provided Class that matches this resolver's
+ * Find a single Method on the provided Object that matches this resolver's
* criteria.
*
- * @param clazz the Class on which to search for a Method
+ * @param candidate the candidate Object whose Class should be searched for
+ * a Method
+ *
+ * @return a single Method or null if no Method matching this
+ * resolver's criteria can be found.
+ *
+ * @throws IllegalArgumentException if more than one Method defined on the
+ * given candidate's Class matches this resolver's criteria
+ */
+ Method findMethod(Object candidate) throws IllegalArgumentException;
+
+ /**
+ * Find a single Method on the given Class that matches this
+ * resolver's criteria.
+ *
+ * @param clazz the Class instance on which to search for a Method
*
* @return a single Method or null if no Method matching this
* resolver's criteria can be found.
@@ -37,6 +52,6 @@ public interface MethodResolver {
* @throws IllegalArgumentException if more than one Method defined on the
* given Class matches this resolver's criteria
*/
- Method findMethod(Class> clazz) throws IllegalArgumentException;
+ Method findMethod(Class> clazz);
}
diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/util/DefaultMethodResolverTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/util/DefaultMethodResolverTests.java
index cef1bd7147..9161af8e5c 100644
--- a/org.springframework.integration/src/test/java/org/springframework/integration/util/DefaultMethodResolverTests.java
+++ b/org.springframework.integration/src/test/java/org/springframework/integration/util/DefaultMethodResolverTests.java
@@ -16,6 +16,7 @@
package org.springframework.integration.util;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -27,6 +28,14 @@ import java.lang.reflect.Method;
import org.junit.Test;
+import org.springframework.aop.framework.ProxyFactory;
+import org.springframework.integration.annotation.ServiceActivator;
+import org.springframework.integration.channel.DirectChannel;
+import org.springframework.integration.channel.QueueChannel;
+import org.springframework.integration.endpoint.ServiceActivatorEndpoint;
+import org.springframework.integration.endpoint.SubscribingConsumerEndpoint;
+import org.springframework.integration.message.StringMessage;
+
/**
* @author Mark Fisher
*/
@@ -65,6 +74,38 @@ public class DefaultMethodResolverTests {
assertNull(method);
}
+ @Test
+ public void jdkProxy() {
+ DirectChannel input = new DirectChannel();
+ QueueChannel output = new QueueChannel();
+ GreetingService testBean = new GreetingBean();
+ ProxyFactory proxyFactory = new ProxyFactory(testBean);
+ proxyFactory.setProxyTargetClass(false);
+ testBean = (GreetingService) proxyFactory.getProxy();
+ ServiceActivatorEndpoint consumer = new ServiceActivatorEndpoint(testBean);
+ consumer.setOutputChannel(output);
+ SubscribingConsumerEndpoint endpoint = new SubscribingConsumerEndpoint(consumer, input);
+ endpoint.start();
+ input.send(new StringMessage("proxy"));
+ assertEquals("hello proxy", output.receive(0).getPayload());;
+ }
+
+ @Test
+ public void cglibProxy() {
+ DirectChannel input = new DirectChannel();
+ QueueChannel output = new QueueChannel();
+ GreetingService testBean = new GreetingBean();
+ ProxyFactory proxyFactory = new ProxyFactory(testBean);
+ proxyFactory.setProxyTargetClass(true);
+ testBean = (GreetingService) proxyFactory.getProxy();
+ ServiceActivatorEndpoint consumer = new ServiceActivatorEndpoint(testBean);
+ consumer.setOutputChannel(output);
+ SubscribingConsumerEndpoint endpoint = new SubscribingConsumerEndpoint(consumer, input);
+ endpoint.start();
+ input.send(new StringMessage("proxy"));
+ assertEquals("hello proxy", output.receive(0).getPayload());;
+ }
+
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@@ -130,4 +171,27 @@ public class DefaultMethodResolverTests {
}
}
+
+ public interface GreetingService {
+
+ String sayHello(String s);
+
+ }
+
+
+ public static class GreetingBean implements GreetingService {
+
+ private String greeting = "hello";
+
+ public void setGreeting(String greeting) {
+ this.greeting = greeting;
+ }
+
+ @ServiceActivator
+ public String sayHello(String name) {
+ return greeting + " " + name;
+ }
+
+ }
+
}