diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/AbstractStandardMessageHandlerFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/config/AbstractStandardMessageHandlerFactoryBean.java
index 2c4a3f1b8b..a6b0605532 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/AbstractStandardMessageHandlerFactoryBean.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/AbstractStandardMessageHandlerFactoryBean.java
@@ -77,10 +77,10 @@ abstract class AbstractStandardMessageHandlerFactoryBean extends AbstractSimpleM
if (this.targetObject != null) {
Assert.state(this.expression == null,
"The 'targetObject' and 'expression' properties are mutually exclusive.");
- boolean targetIsDirectReplyProducingHandler = this.extractTypeIfPossible(targetObject,
- AbstractReplyProducingMessageHandler.class) != null
- && this.canBeUsedDirect(
- (AbstractReplyProducingMessageHandler) targetObject) // give subclasses a say
+ AbstractReplyProducingMessageHandler actualHandler = this.extractTypeIfPossible(targetObject,
+ AbstractReplyProducingMessageHandler.class);
+ boolean targetIsDirectReplyProducingHandler = actualHandler != null
+ && this.canBeUsedDirect(actualHandler) // give subclasses a say
&& this.methodIsHandleMessageOrEmpty(this.targetMethodName);
if (this.targetObject instanceof MessageProcessor>) {
handler = this.createMessageProcessingHandler((MessageProcessor>) this.targetObject);
@@ -89,9 +89,9 @@ abstract class AbstractStandardMessageHandlerFactoryBean extends AbstractSimpleM
if (logger.isDebugEnabled()) {
logger.debug("Wiring handler (" + beanName + ") directly into endpoint");
}
+ this.checkReuse(actualHandler);
+ this.postProcessReplyProducer(actualHandler);
handler = (MessageHandler) targetObject;
- this.checkReuse((AbstractReplyProducingMessageHandler) handler);
- this.postProcessReplyProducer((AbstractReplyProducingMessageHandler) handler);
}
else {
handler = this.createMethodInvokingHandler(this.targetObject, this.targetMethodName);
@@ -120,7 +120,7 @@ abstract class AbstractStandardMessageHandlerFactoryBean extends AbstractSimpleM
}
private void checkReuse(AbstractReplyProducingMessageHandler replyHandler) {
- Assert.isTrue(!referencedReplyProducers.contains(targetObject),
+ Assert.isTrue(!referencedReplyProducers.contains(replyHandler),
"An AbstractReplyProducingMessageHandler may only be referenced once (" +
replyHandler.getComponentName() + ") - use scope=\"prototype\"");
referencedReplyProducers.add(replyHandler);
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/handler/ServiceActivatorDefaultFrameworkMethodTests.java b/spring-integration-core/src/test/java/org/springframework/integration/handler/ServiceActivatorDefaultFrameworkMethodTests.java
index 152b41f15e..4756857945 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/handler/ServiceActivatorDefaultFrameworkMethodTests.java
+++ b/spring-integration-core/src/test/java/org/springframework/integration/handler/ServiceActivatorDefaultFrameworkMethodTests.java
@@ -94,7 +94,7 @@ public class ServiceActivatorDefaultFrameworkMethodTests {
}
@Test
- public void testNotOptimizedReplyingMessageHandler() {
+ public void testOptimizedReplyingMessageHandler() {
QueueChannel replyChannel = new QueueChannel();
Message> message = MessageBuilder.withPayload("test").setReplyChannel(replyChannel).build();
this.optimizedRefReplyingHandlerTestInputChannel.send(message);
diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/ServiceActivatorDefaultFrameworkMethodTests-context.xml b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/ServiceActivatorDefaultFrameworkMethodTests-context.xml
new file mode 100644
index 0000000000..a222fe42dc
--- /dev/null
+++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/ServiceActivatorDefaultFrameworkMethodTests-context.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/ServiceActivatorDefaultFrameworkMethodTests.java b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/ServiceActivatorDefaultFrameworkMethodTests.java
new file mode 100644
index 0000000000..90ad33084d
--- /dev/null
+++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/ServiceActivatorDefaultFrameworkMethodTests.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.integration.jmx;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.integration.Message;
+import org.springframework.integration.MessageChannel;
+import org.springframework.integration.channel.QueueChannel;
+import org.springframework.integration.core.MessageHandler;
+import org.springframework.integration.endpoint.EventDrivenConsumer;
+import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
+import org.springframework.integration.handler.MessageProcessor;
+import org.springframework.integration.support.MessageBuilder;
+import org.springframework.integration.test.util.TestUtils;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * See INT-1688 for background.
+ *
+ * @author Mark Fisher
+ * @author Artem Bilan
+ * @author Gary Russell
+ * @since 2.0.1
+ */
+@ContextConfiguration
+@RunWith(SpringJUnit4ClassRunner.class)
+public class ServiceActivatorDefaultFrameworkMethodTests {
+
+ @Autowired
+ private MessageChannel gatewayTestInputChannel;
+
+ @Autowired
+ private MessageChannel replyingHandlerTestInputChannel;
+
+ @Autowired
+ private MessageChannel optimizedRefReplyingHandlerTestInputChannel;
+
+ @Autowired
+ private MessageChannel replyingHandlerWithStandardMethodTestInputChannel;
+
+ @Autowired
+ private MessageChannel replyingHandlerWithOtherMethodTestInputChannel;
+
+ @Autowired
+ private MessageChannel handlerTestInputChannel;
+
+ @Autowired
+ private MessageChannel processorTestInputChannel;
+
+ @Autowired
+ private EventDrivenConsumer processorTestService;
+
+ @Autowired
+ private MessageProcessor> testMessageProcessor;
+
+ @Test
+ public void testGateway() {
+ QueueChannel replyChannel = new QueueChannel();
+ Message> message = MessageBuilder.withPayload("test").setReplyChannel(replyChannel).build();
+ this.gatewayTestInputChannel.send(message);
+ Message> reply = replyChannel.receive(0);
+ assertEquals("gatewayTestInputChannel,gatewayTestService,gateway,requestChannel,bridge,replyChannel", reply.getHeaders().get("history").toString());
+ }
+
+ @Test
+ public void testReplyingMessageHandler() {
+ QueueChannel replyChannel = new QueueChannel();
+ Message> message = MessageBuilder.withPayload("test").setReplyChannel(replyChannel).build();
+ this.replyingHandlerTestInputChannel.send(message);
+ Message> reply = replyChannel.receive(0);
+ assertEquals("TEST", reply.getPayload());
+ assertEquals("replyingHandlerTestInputChannel,replyingHandlerTestService", reply.getHeaders().get("history").toString());
+ StackTraceElement[] st = (StackTraceElement[]) reply.getHeaders().get("callStack");
+ assertEquals("doDispatch", st[15].getMethodName()); // close to the metal
+ }
+
+ @Test
+ public void testOptimizedReplyingMessageHandler() {
+ QueueChannel replyChannel = new QueueChannel();
+ Message> message = MessageBuilder.withPayload("test").setReplyChannel(replyChannel).build();
+ this.optimizedRefReplyingHandlerTestInputChannel.send(message);
+ Message> reply = replyChannel.receive(0);
+ assertEquals("TEST", reply.getPayload());
+ assertEquals("optimizedRefReplyingHandlerTestInputChannel,optimizedRefReplyingHandlerTestService",
+ reply.getHeaders().get("history").toString());
+ StackTraceElement[] st = (StackTraceElement[]) reply.getHeaders().get("callStack");
+ assertEquals("doDispatch", st[15].getMethodName());
+ }
+
+ @Test
+ public void testReplyingMessageHandlerWithStandardMethod() {
+ QueueChannel replyChannel = new QueueChannel();
+ Message> message = MessageBuilder.withPayload("test").setReplyChannel(replyChannel).build();
+ this.replyingHandlerWithStandardMethodTestInputChannel.send(message);
+ Message> reply = replyChannel.receive(0);
+ assertEquals("TEST", reply.getPayload());
+ assertEquals("replyingHandlerWithStandardMethodTestInputChannel,replyingHandlerWithStandardMethodTestService", reply.getHeaders().get("history").toString());
+ StackTraceElement[] st = (StackTraceElement[]) reply.getHeaders().get("callStack");
+ assertEquals("doDispatch", st[15].getMethodName()); // close to the metal
+ }
+
+ @Test
+ public void testReplyingMessageHandlerWithOtherMethod() {
+ QueueChannel replyChannel = new QueueChannel();
+ Message> message = MessageBuilder.withPayload("test").setReplyChannel(replyChannel).build();
+ this.replyingHandlerWithOtherMethodTestInputChannel.send(message);
+ Message> reply = replyChannel.receive(0);
+ assertEquals("bar", reply.getPayload());
+ assertEquals("replyingHandlerWithOtherMethodTestInputChannel,replyingHandlerWithOtherMethodTestService", reply.getHeaders().get("history").toString());
+ }
+
+ @Test
+ public void testMessageHandler() {
+ QueueChannel replyChannel = new QueueChannel();
+ Message> message = MessageBuilder.withPayload("test").setReplyChannel(replyChannel).build();
+ this.handlerTestInputChannel.send(message);
+ }
+
+// INT-2399
+ @Test
+ public void testMessageProcessor() {
+ Object processor = TestUtils.getPropertyValue(processorTestService, "handler.h.advised.targetSource.target.processor");
+ assertSame(testMessageProcessor, processor);
+
+ QueueChannel replyChannel = new QueueChannel();
+ Message> message = MessageBuilder.withPayload("bar").setReplyChannel(replyChannel).build();
+ this.processorTestInputChannel.send(message);
+ Message> reply = replyChannel.receive(0);
+ assertEquals("foo:bar", reply.getPayload());
+ assertEquals("processorTestInputChannel,processorTestService", reply.getHeaders().get("history").toString());
+ }
+
+ private interface Foo {
+
+ public String foo(String in);
+
+ }
+
+ @SuppressWarnings("unused")
+ private static class TestReplyingMessageHandler extends AbstractReplyProducingMessageHandler implements Foo {
+
+ @Override
+ protected Object handleRequestMessage(Message> requestMessage) {
+ Exception e = new RuntimeException();
+ StackTraceElement[] st = e.getStackTrace();
+ return MessageBuilder.withPayload(requestMessage.getPayload().toString().toUpperCase())
+ .setHeader("callStack", st);
+ }
+
+ public String foo(String in) {
+ return "bar";
+ }
+
+ }
+
+ @SuppressWarnings("unused")
+ private static class TestMessageHandler implements MessageHandler {
+
+ @Override
+ public void handleMessage(Message> requestMessage) {
+ Exception e = new RuntimeException();
+ StackTraceElement[] st = e.getStackTrace();
+ assertEquals("doDispatch", st[28].getMethodName());
+ }
+ }
+
+ @SuppressWarnings("unused")
+ private static class TestMessageProcessor implements MessageProcessor {
+
+ private String prefix;
+
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
+
+ public String processMessage(Message> message) {
+ return prefix + ":" + message.getPayload();
+ }
+ }
+
+}