重复
重复
重复模板
批处理是关于重复作的,无论是作为简单的优化还是作为一部分
工作。制定战略并概括重复,并提供相当于一个
iterator 框架,Spring Batch 具有RepeatOperations接口。这RepeatOperations接口具有以下定义:
public interface RepeatOperations {
RepeatStatus iterate(RepeatCallback callback) throws RepeatException;
}
回调是一个接口,如以下定义所示,允许您插入 一些业务逻辑需要重复:
public interface RepeatCallback {
RepeatStatus doInIteration(RepeatContext context) throws Exception;
}
回调会重复执行,直到实现确定
迭代应该结束。这些接口中的返回值是一个枚举,可以
要么是RepeatStatus.CONTINUABLE或RepeatStatus.FINISHED.一个RepeatStatus枚举向重复作的调用方传达有关是否
还有更多工作要做。一般来说,实现RepeatOperations应检查RepeatStatus并将其用作终止
迭 代。任何希望向调用方发出信号表明没有更多工作可做的回调
do 可以返回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,循环的终止iterate方法是
由CompletionPolicy,这也是一家工厂RepeatContext.这RepeatTemplate有责任使用当前策略创建RepeatContext并将其传递给RepeatCallback在迭代的每个阶段。
回调完成后,其doInIteration这RepeatTemplate得打个电话
到CompletionPolicy要求它更新其状态(将存储在RepeatContext).然后,它会询问策略迭代是否完成。
Spring Batch 提供了一些简单的通用实现CompletionPolicy.SimpleCompletionPolicy允许执行最多固定次数(使用RepeatStatus.FINISHED随时强制提前完成)。
用户可能需要实现自己的完成策略,以实现更复杂的 决定。例如,阻止批处理作业执行的批处理窗口 一旦在线系统投入使用,就需要自定义策略。
异常处理
如果在RepeatCallback这RepeatTemplate咨询
一ExceptionHandler,它可以决定是否重新抛出异常。
以下列表显示了ExceptionHandler接口定义:
public interface ExceptionHandler {
void handleException(RepeatContext context, Throwable throwable)
throws Throwable;
}
一个常见的用例是计算给定类型的异常数,并在
已达到限制。为此,Spring Batch 提供了SimpleLimitExceptionHandler和稍微灵活一些RethrowOnThresholdExceptionHandler.这SimpleLimitExceptionHandler有限制
属性和应与当前异常进行比较的异常类型。都
所提供类型的子类也被计算在内。给定类型的例外情况是
在达到限制之前忽略,然后重新抛出它们。其他类型的例外情况
总是被重新抛出。
重要的可选属性SimpleLimitExceptionHandler是布尔标志
叫useParent.是的false默认情况下,因此限制仅在
当前RepeatContext.当设置为true,则限制在
嵌套迭代(例如步骤中的一组块)。
听众
通常,能够接收针对跨领域问题的额外回调很有用
跨越许多不同的迭代。为此,Spring Batch 提供了RepeatListener接口。这RepeatTemplate允许用户注册RepeatListener实现,并且它们会被赋予带有RepeatContext和RepeatStatus(在迭代期间可用)。
这RepeatListener接口具有以下定义:
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不限于执行回调
顺序。非常重要的是,某些实现能够执行其
并行回调。为此,Spring Batch 提供了TaskExecutorRepeatTemplate,它使用 SpringTaskExecutor策略来运行RepeatCallback.默认情况下,使用SynchronousTaskExecutor,这有效果
在同一线程中执行整个迭代(与普通线程相同RepeatTemplate).
声明式迭代
有时,您知道每次都想重复一些业务处理
它发生了。这方面的典型示例是消息管道的优化。是的
如果一批消息经常到达,则处理它们比处理
承担每条消息的单独事务费用。Spring Batch 提供 AOP
将方法调用包装在RepeatOperations对象
目的。这RepeatOperationsInterceptor执行截获的方法并重复
根据CompletionPolicy在提供的RepeatTemplate.
以下示例显示了使用 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"/>
以下示例演示了如何使用 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;
}
前面的示例使用默认的RepeatTemplate拦截器内部。更改
策略、侦听器和其他详细信息,您可以注入RepeatTemplate进入拦截器。
如果截获的方法返回void,则拦截器始终返回RepeatStatus.CONTINUABLE(因此,如果CompletionPolicy没有有限的终点)。否则,它返回RepeatStatus.CONTINUABLE直到截获方法的返回值为null,
此时它返回RepeatStatus.FINISHED.因此,业务逻辑
在目标方法内部可以通过返回来表示没有更多工作可做null或者通过抛出由ExceptionHandler在提供的RepeatTemplate.