重复
重复
RepeatTemplate (重复模板)
批处理是关于重复作的,无论是作为简单的优化还是作为一部分
的工作。为了制定和概括重复,并提供相当于
iterator 框架中,Spring Batch 具有RepeatOperations
接口。这RepeatOperations
interface 的定义如下:
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
并将其用作结束
迭 代。任何希望向调用方发出信号,表明没有更多工作的回调
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
method 为
由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
(在迭代期间可用)。
这RepeatListener
interface 的定义如下:
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 将方法调用包装在RepeatOperations
object for this (对象)
目的。这RepeatOperationsInterceptor
执行 intercepted 方法并重复
根据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
直到 intercepted 方法的返回值为null
,
此时,它会返回RepeatStatus.FINISHED
.因此,业务逻辑
可以通过返回null
或者通过抛出由ExceptionHandler
在提供的RepeatTemplate
.