重复
重复
重复模板
批处理是关于重复作的,无论是作为简单的优化还是作为一部分
工作。制定战略并概括重复,并提供相当于一个
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
并将其用作终止
迭 代。任何希望向调用方发出没有工作的信号的回调仍然存在
可以返回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 拦截器,请参阅
<<https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#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 拦截器,请参阅
<<https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#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
.