Sometimes there is some business processing that you know you want
to repeat every time it happens. The classic example of this is the
optimization of a message pipeline - it is more efficient to process a
batch of messages, if they are arriving frequently, than to bear the cost
of a separate transaction for every message. Spring Batch provides an AOP
interceptor that wraps a method call in a
RepeatOperations for just this purpose. The
RepeatOperationsInterceptor executes the
intercepted method and repeats according to the
CompletionPolicy in the provided
RepeatTemplate.
Here is an example of declarative iteration using the Spring AOP
namespace to repeat a service call to a method called
processMessage (for more detail on how to
configure AOP interceptors see the Spring User Guide):
<aop:config>
<aop:pointcut id="transactional"
expression="execution(* com..*Service.processMessage(..))" />
<aop:advisor pointcut-ref="transactional"
advice-ref="retryAdvice" order="-1"/>
</aop:config>
<bean id="retryAdvice" class="org.spr...RepeatOperationsInterceptor"/>The example above uses a default
RepeatTemplate inside the interceptor. To change
the policies, listeners etc. you only need to inject an instance of
RepeatTemplate into the interceptor.
If the intercepted method returns void then the
interceptor always returns ExitStatus.CONTINUABLE (so there is a danger of
an infinite loop if the CompletionPolicy does not
have a finite end point). Otherwise it returns
ExitStatus.CONTINUABLE until the return value from the
intercepted method is null, at which point it returns
ExitStatus.FINISHED. So the business logic inside the target
method can signal that there is no more work to do by returning
null, or by throwing an exception that is re-thrown by the
ExceptionHandler in the provided
RepeatTemplate.