重复

重复

RepeatTemplate (重复模板)

批处理是关于重复操作的,无论是作为简单的优化还是作为一部分 的工作。为了制定和概括重复,并提供相当于 iterator 框架,Spring Batch 具有该接口。该接口具有以下定义:RepeatOperationsRepeatOperationsspring-doc.cn

public interface RepeatOperations {

    RepeatStatus iterate(RepeatCallback callback) throws RepeatException;

}

回调是一个接口,如以下定义所示,允许您将 一些需要重复的业务逻辑:spring-doc.cn

public interface RepeatCallback {

    RepeatStatus doInIteration(RepeatContext context) throws Exception;

}

重复执行回调,直到 implementation 确定 iteration 应该结束。这些接口中的返回值是一个枚举,它可以 be 或 .枚举将信息传达给重复操作的调用方,说明是否 还有更多的工作要做。一般来说,的实现应该检查 the 并将其用作结束 迭 代。任何希望向调用方发出信号,表明没有更多工作的回调 do 可以返回 。RepeatStatus.CONTINUABLERepeatStatus.FINISHEDRepeatStatusRepeatOperationsRepeatStatusRepeatStatus.FINISHEDspring-doc.cn

最简单的通用实现是 ,因为 如以下示例所示:RepeatOperationsRepeatTemplatespring-doc.cn

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.CONTINUABLERepeatStatus.FINISHEDspring-doc.cn

RepeatContext

的 method 参数是一个 .许多回调会忽略 上下文。但是,如有必要,它可以用作属性包来存储 transient 数据。方法返回后,上下文 已不复存在。RepeatCallbackRepeatContextiteratespring-doc.cn

如果正在进行嵌套迭代,则 a 具有父上下文。这 父上下文有时可用于存储需要共享的数据 对 .例如,如果您想计算 事件的发生次数,并在后续调用中记住它。RepeatContextiteratespring-doc.cn

RepeatStatus (重复状态)

RepeatStatus是 Spring Batch 使用的枚举,用于指示处理是否具有 完成。它有两个可能的值,如下表所述:RepeatStatusspring-doc.cn

表 1.RepeatStatus 属性

spring-doc.cn

描述spring-doc.cn

CONTINUABLE (持续)spring-doc.cn

还有更多的工作要做。spring-doc.cn

完成spring-doc.cn

不应再发生重复。spring-doc.cn

RepeatStatus还可以使用 中的方法将 values 与逻辑 AND 运算结合使用。这样做的效果是对 continuable 标志。换句话说,如果任一状态为 ,则结果为 。and()RepeatStatusFINISHEDFINISHEDspring-doc.cn

完成策略

在 中,方法中循环的终止是 由 确定,它也是 的工厂。它有责任使用当前策略来创建 a 并将其传递给迭代的每个阶段。 回调完成其 后,必须进行调用 添加到 中,要求它更新其状态(将存储在 中)。然后,它会询问策略迭代是否完成。RepeatTemplateiterateCompletionPolicyRepeatContextRepeatTemplateRepeatContextRepeatCallbackdoInIterationRepeatTemplateCompletionPolicyRepeatContextspring-doc.cn

Spring Batch 提供了一些简单的通用实现。 允许执行最多固定次数(随时强制提前完成)。CompletionPolicySimpleCompletionPolicyRepeatStatus.FINISHEDspring-doc.cn

对于更复杂的情况,用户可能需要实施自己的完成策略 决定。例如,阻止批处理作业执行的批处理窗口 一旦在线系统投入使用,将需要一个自定义策略。spring-doc.cn

异常处理

如果在 中引发了异常,则 会查阅 an ,它可以决定是否重新引发异常。RepeatCallbackRepeatTemplateExceptionHandlerspring-doc.cn

下面的清单显示了接口定义:ExceptionHandlerspring-doc.cn

public interface ExceptionHandler {

    void handleException(RepeatContext context, Throwable throwable)
        throws Throwable;

}

一个常见的用例是计算给定类型的异常数量,并在 达到 limit 时。为此, Spring Batch 提供了 和 稍微灵活一些。有限制 属性和异常类型,该类型应与当前异常进行比较。都 provided type 的子类也会被计算在内。给定类型的异常是 ignored 直到达到限制,然后重新抛出它们。其他类型的异常 总是被重新抛出。SimpleLimitExceptionHandlerRethrowOnThresholdExceptionHandlerSimpleLimitExceptionHandlerspring-doc.cn

的一个重要可选属性是 boolean 标志 叫。默认情况下,该限制仅计入 当前。当设置为 时,该限制将保留在 嵌套迭代(例如步骤中的一组块)。SimpleLimitExceptionHandleruseParentfalseRepeatContexttruespring-doc.cn

听众

通常,能够接收横切关注点的其他回调是很有用的 在许多不同的迭代中。为此,Spring Batch 提供了接口。这允许用户注册实现,并在迭代期间向他们提供带有 和 的回调(如果可用)。RepeatListenerRepeatTemplateRepeatListenerRepeatContextRepeatStatusspring-doc.cn

该接口具有以下定义:RepeatListenerspring-doc.cn

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);
}

and 回调出现在整个迭代之前和之后。、 和 应用于各个调用。openclosebeforeafteronErrorRepeatCallbackspring-doc.cn

请注意,当有多个侦听器时,它们位于一个列表中,因此有一个 次序。在这种情况下, and 以相同的顺序调用,而 , , 和 以相反的顺序调用。openbeforeafteronErrorclosespring-doc.cn

并行处理

的实现不限于执行回调 顺序。一些 implementation 能够执行其 callback 的 Alpha 函数。为此,Spring Batch 提供了 ,它使用 Spring 策略来运行 .默认使用 ,它具有 在同一线程中执行整个迭代(与 normal 相同)。RepeatOperationsTaskExecutorRepeatTemplateTaskExecutorRepeatCallbackSynchronousTaskExecutorRepeatTemplatespring-doc.cn

声明式迭代

有时,您知道每次都要重复一些业务处理 它发生了。这方面的经典示例是消息管道的优化。是的 如果消息频繁到达,则处理一批消息比处理一批消息更有效 承担每条消息的单独交易费用。Spring Batch 提供 AOP interceptor 将方法调用包装在对象中,仅用于此 目的。执行 intercepted 方法并重复 根据 中提供的 .RepeatOperationsRepeatOperationsInterceptorCompletionPolicyRepeatTemplatespring-doc.cn

以下示例显示了使用 Spring AOP 名称空间的声明式迭代 对调用的方法重复服务调用(有关如何 配置 AOP 拦截器,请参阅 Spring 用户指南):processMessagespring-doc.cn

<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 配置来 对调用的方法重复服务调用(有关如何 配置 AOP 拦截器,请参阅 Spring 用户指南):processMessagespring-doc.cn

@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;
}

前面的示例在拦截器中使用 default。更改 策略、侦听器和其他详细信息,您可以将 的实例注入拦截器中。RepeatTemplateRepeatTemplatespring-doc.cn

如果被拦截的方法返回 ,则拦截器总是返回(因此,如果 没有有限的终点,则存在无限循环的危险)。否则,它将返回,直到截获的方法的返回值为 , 此时它返回 。因此,业务逻辑 中,目标方法可以通过返回或引发由提供的 .voidRepeatStatus.CONTINUABLECompletionPolicyRepeatStatus.CONTINUABLEnullRepeatStatus.FINISHEDnullExceptionHandlerRepeatTemplatespring-doc.cn