diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/AbstractReplyProducingMessageHandler.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/AbstractReplyProducingMessageHandler.java
index ca6c2f9dab..beda2d4c8f 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/handler/AbstractReplyProducingMessageHandler.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/handler/AbstractReplyProducingMessageHandler.java
@@ -138,6 +138,18 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
protected abstract Object handleRequestMessage(Message> requestMessage);
+ /**
+ * An implementation of this interface is used to wrap the
+ * {@link AbstractReplyProducingMessageHandler#handleRequestMessage(Message)}
+ * method. Also allows access to the underlying
+ * {@link AbstractReplyProducingMessageHandler} to obtain properties.
+ *
+ * @author Gary Russell
+ * @since 2.2
+ *
+ * @see #getAdvisedHandler()
+ *
+ */
public interface RequestHandler {
Object handleRequestMessage(Message> requestMessage);
@@ -145,6 +157,18 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
@Override
String toString();
+ /**
+ * Utility method, intended for use in message handler advice classes to get
+ * information about the advised object. For example:
+ *
+ * {@code ((AbstractReplyProducingMessageHandler.RequestHandler)
+ * invocation.getThis()).getAdvisedHandler().getComponentName()}
+ * @return the outer class instance.
+ *
+ * @since 4.3.2
+ */
+ AbstractReplyProducingMessageHandler getAdvisedHandler();
+
}
private class AdvisedRequestHandler implements RequestHandler {
@@ -159,6 +183,11 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
return AbstractReplyProducingMessageHandler.this.toString();
}
+ @Override
+ public AbstractReplyProducingMessageHandler getAdvisedHandler() {
+ return AbstractReplyProducingMessageHandler.this;
+ }
+
}
}
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/handler/advice/AdvisedMessageHandlerTests.java b/spring-integration-core/src/test/java/org/springframework/integration/handler/advice/AdvisedMessageHandlerTests.java
index 94e882a17f..c5e3eb2652 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/handler/advice/AdvisedMessageHandlerTests.java
+++ b/spring-integration-core/src/test/java/org/springframework/integration/handler/advice/AdvisedMessageHandlerTests.java
@@ -132,6 +132,8 @@ public class AdvisedMessageHandlerTests {
return "baz";
}
};
+ String componentName = "testComponentName";
+ handler.setComponentName(componentName);
QueueChannel replies = new QueueChannel();
handler.setOutputChannel(replies);
Message message = new GenericMessage("Hello, world!");
@@ -153,6 +155,17 @@ public class AdvisedMessageHandlerTests {
List adviceChain = new ArrayList();
adviceChain.add(advice);
+ final AtomicReference compName = new AtomicReference();
+ adviceChain.add(new AbstractRequestHandlerAdvice() {
+
+ @Override
+ protected Object doInvoke(ExecutionCallback callback, Object target, Message> message) throws Exception {
+ compName.set(((AbstractReplyProducingMessageHandler.RequestHandler) target).getAdvisedHandler()
+ .getComponentName());
+ return callback.execute();
+ }
+
+ });
handler.setAdviceChain(adviceChain);
handler.setBeanFactory(mock(BeanFactory.class));
handler.afterPropertiesSet();
@@ -163,6 +176,8 @@ public class AdvisedMessageHandlerTests {
assertNotNull(reply);
assertEquals("baz", reply.getPayload());
+ assertEquals(componentName, compName.get());
+
Message> success = successChannel.receive(1000);
assertNotNull(success);
assertEquals("Hello, world!", ((AdviceMessage>) success).getInputMessage().getPayload());
diff --git a/src/reference/asciidoc/handler-advice.adoc b/src/reference/asciidoc/handler-advice.adoc
index aafa627446..685e2b62d6 100644
--- a/src/reference/asciidoc/handler-advice.adoc
+++ b/src/reference/asciidoc/handler-advice.adoc
@@ -395,7 +395,7 @@ If you wish to suppress throwing the exception, set the `trapException` property
==== Custom Advice Classes
In addition to the provided Advice classes above, you can implement your own Advice classes.
-While you can provide any implementation of `org.aopalliance.aop.Advice`, it is generally recommended that you subclass `o.s.i.handler.advice.AbstractRequestHandlerAdvice`.
+While you can provide any implementation of `org.aopalliance.aop.Advice` (usually `org.aopalliance.intercept.MethodInterceptor`), it is generally recommended that you subclass `o.s.i.handler.advice.AbstractRequestHandlerAdvice`.
This has the benefit of avoiding writing low-level _Aspect Oriented Programming_ code as well as providing a starting point that is specifically tailored for use in this environment.
Subclasses need to implement the `doInvoke()`` method:
@@ -530,6 +530,42 @@ You may want to place the retry advice advice first, followed by the transaction
Then, each retry will be performed in a new transaction.
On the other hand, if you want all the attempts, and any recovery operations (in the retry `RecoveryCallback`), to be scoped within the transaction, you would put the transaction advice first.
+[[advised-handler-properties]]
+==== Advised Handler Properties
+
+Sometimes, it is useful to access handler properties from within the advice.
+For example, most handlers implement `NamedComponent` and you can access the component name.
+
+The target object can be accessed via the `target` argument when subclassing `AbstractRequestHandlerAdvice` or
+`invocation.getThis()` when implementing `org.aopalliance.intercept.MethodInterceptor`.
+
+When the entire handler is advised (such as when the handler does not produce replies, or the advice implements `HandleMessageAdvice`), you can simply cast the target object to the desired implemented interface, such as `NamedComponent`.
+
+[source, java]
+----
+String componentName = ((NamedComponent) target).getComponentName();
+----
+
+or
+
+[source, java]
+----
+String componentName = ((NamedComponent) invocation.getThis()).getComponentName();
+----
+
+when implementing `MethodInterceptor` directly.
+
+When only the `handleRequestMessage()` method is advised (in a reply-producing handler), you need to access the
+full handler, which is an `AbstractReplyProducingMessageHandler`...
+
+[source, java]
+----
+AbstractReplyProducingMessageHandler handler =
+ ((AbstractReplyProducingMessageHandler.RequestHandler) target).getAdvisedHandler();
+
+String componentName = handler.getComponentName();
+----
+
[[idempotent-receiver]]
==== Idempotent Receiver Enterprise Integration Pattern