INT-2858: Fix for Repeatable invocation.proceed()
Heretofore there wasn't ability to make some scenario like this, when we want to make failure notification on each retry:
<service-activator>
<request-handler-advice-chain>
<bean class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice"/>
<bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice"
p:onFailureExpression="#exception" p:failureChannel-ref="errorOnEachRetryChannel"/>
</request-handler-advice-chain>
</service-activator>
The second Advice was invoked only once. This was because `ProxyMethodInvocation` keeps the index of current interceptor
on each `invocation.proceed()`, which is recursive by design.
So, change `AbstractRequestHandlerAdvice` to use `((ProxyMethodInvocation) invocation).invocableClone().proceed();`
This way, we get a fresh `MethodInvocation` for the current `Advice` with nested desired advices.
JIRA: https://jira.springsource.org/browse/INT-2858
INT-2858: Polishing; PR Comments
Introduce `AbstractRequestHandlerAdvice.ExecutionCallback#cloneAndExecute()` especially for repeatable Advices, e.g. `RequestHandlerRetryAdvice`
to avoid overhead from `clone()` on simple Advices
INT-2858: Doc ExecutionCallback#cloneAndExecute()
INT-2858 Polishing
Rework docs; add Javadoc; add to test case.
This commit is contained in:
committed by
Gary Russell
parent
0ff2a2027b
commit
a994b40b47
@@ -66,9 +66,9 @@
|
||||
standard Advices are provided:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>MessageHandlerRetryAdvice</listitem>
|
||||
<listitem>MessageHandlerCircuitBreakerAdvice</listitem>
|
||||
<listitem>ExpressionEvaluatingMessageHandlerAdvice</listitem>
|
||||
<listitem>RequestHandlerRetryAdvice</listitem>
|
||||
<listitem>RequestHandlerCircuitBreakerAdvice</listitem>
|
||||
<listitem>ExpressionEvaluatingRequestHandlerAdvice</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
These are each described in detail in the following sections.
|
||||
@@ -148,7 +148,7 @@ DEBUG [task-scheduler-2]Retry failed last attempt: count=3]]></programlisting></
|
||||
<para><emphasis>Simple Stateless Retry with Recovery</emphasis></para>
|
||||
<para>
|
||||
This example adds a <classname>RecoveryCallback</classname> to the
|
||||
above example; it uses a <classname></classname>
|
||||
above example; it uses a <classname>ErrorMessageSendingRecoverer</classname>
|
||||
to send an <emphasis>ErrorMessage</emphasis> to a channel.
|
||||
</para>
|
||||
<para><programlisting><![CDATA[<int:service-activator input-channel="input" ref="failer" method="service">
|
||||
@@ -448,5 +448,20 @@ Caused by: java.lang.RuntimeException: foo
|
||||
return result;
|
||||
}
|
||||
}]]></programlisting></para>
|
||||
<note>
|
||||
<para>
|
||||
In addition to the <code>execute()</code> method, the <interfacename>ExecutionCallback</interfacename> provides
|
||||
an additional method <code>cloneAndExecute()</code>. This method must be used in cases where the invocation
|
||||
might be called multiple times within a single execution of <code>doInvoke()</code>, such as in the
|
||||
<classname>RequestHandlerRetryAdvice</classname>. This is required because the Spring AOP
|
||||
<classname>org.springframework.aop.framework.ReflectiveMethodInvocation</classname> object maintains state of which
|
||||
advice in a chain was last invoked; this state must be reset for each call.
|
||||
</para>
|
||||
<para>
|
||||
For more information, see the
|
||||
<ulink url="http://static.springsource.org/spring-framework/docs/current/javadoc-api/org/springframework/aop/framework/ReflectiveMethodInvocation.html">
|
||||
ReflectiveMethodInvocation</ulink> JavaDocs.
|
||||
</para>
|
||||
</note>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user