重复
RepeatTemplate (重复模板)
批处理是关于重复作的,无论是作为简单的优化还是作为一部分
的工作。为了制定和概括重复,并提供相当于
iterator 框架中,Spring Batch 具有RepeatOperations接口。这RepeatOperationsinterface 的定义如下:
public interface RepeatOperations {
RepeatStatus iterate(RepeatCallback callback) throws RepeatException;
}
回调是一个接口,如以下定义所示,允许您将 一些需要重复的业务逻辑:
public interface RepeatCallback {
RepeatStatus doInIteration(RepeatContext context) throws Exception;
}
重复执行回调,直到 implementation 确定
iteration 应该结束。这些接口中的返回值是一个枚举值,该值可以
可以是RepeatStatus.CONTINUABLE或RepeatStatus.FINISHED.一个RepeatStatus枚举将信息传达给重复作的调用方,说明是否
任何工作都留下来。一般来说,RepeatOperations应检查RepeatStatus并将其用作结束
迭 代。任何希望向调用方发出没有工作的信号的回调
可以返回RepeatStatus.FINISHED.
最简单的通用实现RepeatOperations是RepeatTemplate:
RepeatTemplate template = new RepeatTemplate();
template.setCompletionPolicy(new SimpleCompletionPolicy(2));
template.iterate(new RepeatCallback() {
public RepeatStatus doInIteration(RepeatContext context) {
// Do stuff in batch...
return RepeatStatus.CONTINUABLE;
}
});
在前面的示例中,我们返回RepeatStatus.CONTINUABLE,以表明存在
还有更多的工作要做。回调还可以返回RepeatStatus.FINISHED,以向
没有工作的调用者。某些迭代可以由
回调中正在完成的工作所固有的注意事项。其他
无限循环(就回调而言),完成决定是
委托给外部策略,如前面的示例所示。
完成策略
在RepeatTemplate,则iteratemethod 为
由CompletionPolicy,它也是RepeatContext.这RepeatTemplate负责使用当前策略创建一个RepeatContext并将其传递给RepeatCallback在迭代的每个阶段。
回调完成其doInIteration这RepeatTemplate必须拨打电话
到CompletionPolicy要求它更新其 state(将存储在RepeatContext).然后,它会询问策略迭代是否完成。
Spring Batch 提供了一些简单的通用实现CompletionPolicy.SimpleCompletionPolicy允许执行最多固定次数(使用RepeatStatus.FINISHED强制随时提前完成)。
对于更复杂的情况,用户可能需要实施自己的完成策略 决定。例如,阻止批处理作业执行的批处理窗口 一旦在线系统投入使用,将需要一个自定义策略。
异常处理
如果在RepeatCallback这RepeatTemplate咨询
一ExceptionHandler,它可以决定是否重新引发异常。
下面的清单显示了ExceptionHandler接口定义:
public interface ExceptionHandler {
void handleException(RepeatContext context, Throwable throwable)
throws Throwable;
}
一个常见的用例是计算给定类型的异常数量,并在
达到 limit 时。为此,Spring Batch 提供了SimpleLimitExceptionHandler并且稍微灵活一些RethrowOnThresholdExceptionHandler.这SimpleLimitExceptionHandler有限制
属性和异常类型,该类型应与当前异常进行比较。都
provided type 的子类也会被计算在内。给定类型的异常是
ignored 直到达到限制,然后重新抛出它们。其他类型的异常
总是被重新抛出。
的一个重要可选属性SimpleLimitExceptionHandler是布尔标志
叫useParent.是的false默认情况下,该限制仅计入
当前RepeatContext.当设置为true,该限制在
嵌套迭代(例如步骤中的一组块)。
听众
通常,能够接收横切关注点的其他回调是很有用的
在许多不同的迭代中。为此,Spring Batch 提供了RepeatListener接口。这RepeatTemplate允许用户注册RepeatListener实现,并且它们会使用RepeatContext和RepeatStatus(在迭代期间可用)。
这RepeatListenerinterface 的定义如下:
public interface RepeatListener {
void before(RepeatContext context);
void after(RepeatContext context, RepeatStatus result);
void open(RepeatContext context);
void onError(RepeatContext context, Throwable e);
void close(RepeatContext context);
}
这open和close回调出现在整个迭代之前和之后。before,after和onError适用于个人RepeatCallback调用。
请注意,当有多个侦听器时,它们位于一个列表中,因此有一个
次序。在这种情况下,open和before以相同的顺序调用,而after,onError和close以相反的顺序调用。
并行处理
的实现RepeatOperations不限于执行回调
顺序。一些 implementation 能够执行其
callback 的 Alpha 函数。为此,Spring Batch 提供了TaskExecutorRepeatTemplate,它使用 SpringTaskExecutor策略来运行RepeatCallback.默认使用SynchronousTaskExecutor,该
在同一线程中执行整个迭代(与正常的RepeatTemplate).
声明式迭代
有时,您知道每次都要重复一些业务处理
它发生了。这方面的经典示例是消息管道的优化。
如果一批消息频繁到达,则处理它们比处理它们更有效
承担每条消息的单独交易费用。Spring Batch 提供 AOP
interceptor 将方法调用包装在RepeatOperationsobject 的
目的。这RepeatOperationsInterceptor执行 intercepted 方法并重复
根据CompletionPolicy在提供的RepeatTemplate.
-
Java
-
XML
以下示例使用 Java 配置来
对名为processMessage(有关如何
配置 AOP 拦截器,请参阅 Spring 用户指南):
@Bean
public MyService myService() {
ProxyFactory factory = new ProxyFactory(RepeatOperations.class.getClassLoader());
factory.setInterfaces(MyService.class);
factory.setTarget(new MyService());
MyService service = (MyService) factory.getProxy();
JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
pointcut.setPatterns(".*processMessage.*");
RepeatOperationsInterceptor interceptor = new RepeatOperationsInterceptor();
((Advised) service).addAdvisor(new DefaultPointcutAdvisor(pointcut, interceptor));
return service;
}
下面的示例展示了使用 Spring AOP 名称空间的声明式迭代
对名为processMessage(有关如何
配置 AOP 拦截器,请参阅 Spring 用户指南):
<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"/>
前面的示例使用默认的RepeatTemplate在拦截器内部。更改
策略、侦听器和其他详细信息中,您可以注入RepeatTemplate进入拦截器。
如果拦截的方法返回void,则拦截器始终返回RepeatStatus.CONTINUABLE(因此,如果存在CompletionPolicy没有有限的终点)。否则,它将返回RepeatStatus.CONTINUABLE直到 intercepted 方法的返回值为null.
此时,它会返回RepeatStatus.FINISHED.因此,业务逻辑
可以通过返回null或者通过引发由ExceptionHandler在提供的RepeatTemplate.