重复

重复

重复模板

批处理是关于重复作的,无论是作为简单的优化还是作为一部分 工作。制定战略并概括重复,并提供相当于一个 iterator 框架,Spring Batch 具有RepeatOperations接口。这RepeatOperations接口具有以下定义:spring-doc.cadn.net.cn

public interface RepeatOperations {

    RepeatStatus iterate(RepeatCallback callback) throws RepeatException;

}

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

public interface RepeatCallback {

    RepeatStatus doInIteration(RepeatContext context) throws Exception;

}

回调会重复执行,直到实现确定 迭代应该结束。这些接口中的返回值是一个枚举值,可以 是RepeatStatus.CONTINUABLERepeatStatus.FINISHED.一个RepeatStatus枚举向重复作的调用方传达有关是否 任何工作都剩下。一般来说,实现RepeatOperations应检查RepeatStatus并将其用作终止 迭 代。任何希望向调用方发出没有工作的信号的回调仍然存在 可以返回RepeatStatus.FINISHED.spring-doc.cadn.net.cn

最简单的通用实现RepeatOperationsRepeatTemplate:spring-doc.cadn.net.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.CONTINUABLE,以表明有 还有更多的工作要做。回调也可以返回RepeatStatus.FINISHED,向 没有工作残留的呼叫者。某些迭代可以通过以下方式终止 回调中正在完成的工作所固有的注意事项。其他人则有效地 无限循环(就回调而言),完成决策为 委托给外部策略,如前面示例所示。spring-doc.cadn.net.cn

重复上下文

的 method 参数RepeatCallback是一个RepeatContext.许多回调忽略 上下文。但是,如有必要,您可以将其用作属性包来存储瞬态 迭代期间的数据。之后iterate方法返回,上下文 不再存在。spring-doc.cadn.net.cn

如果有嵌套迭代正在进行中,则RepeatContext具有父上下文。这 parent context 有时可用于存储需要在 调用iterate.例如,如果您想计算 迭代中事件的发生,并在后续调用中记住它。spring-doc.cadn.net.cn

重复状态

RepeatStatus是 Spring Batch 用来指示处理是否具有 完成。它有两种可能RepeatStatus值:spring-doc.cadn.net.cn

表 1.RepeatStatus 属性

spring-doc.cadn.net.cn

描述spring-doc.cadn.net.cn

CONTINUABLEspring-doc.cadn.net.cn

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

FINISHEDspring-doc.cadn.net.cn

不应再重复。spring-doc.cadn.net.cn

您可以组合RepeatStatus使用and()方法RepeatStatus.这样做的效果是对 continuable 标志。换句话说,如果任一状态为FINISHED,结果是FINISHED.spring-doc.cadn.net.cn

完成政策

在一个RepeatTemplate,循环的终止iterate方法是 由CompletionPolicy,这也是一家工厂RepeatContext.这RepeatTemplate有责任使用当前策略创建RepeatContext并将其传递给RepeatCallback在迭代的每个阶段。 回调完成后,其doInIterationRepeatTemplate得打个电话 到CompletionPolicy要求它更新其状态(将存储在RepeatContext).然后,它会询问策略迭代是否完成。spring-doc.cadn.net.cn

Spring Batch 提供了一些简单的通用实现CompletionPolicy.SimpleCompletionPolicy允许执行最多固定次数(使用RepeatStatus.FINISHED随时强制提前完成)。spring-doc.cadn.net.cn

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

异常处理

如果在RepeatCallbackRepeatTemplate咨询 一ExceptionHandler,它可以决定是否重新抛出异常。spring-doc.cadn.net.cn

以下列表显示了ExceptionHandler接口定义:spring-doc.cadn.net.cn

public interface ExceptionHandler {

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

}

一个常见的用例是计算给定类型的异常数,并在 已达到限制。为此,Spring Batch 提供了SimpleLimitExceptionHandler和稍微灵活一些RethrowOnThresholdExceptionHandler.这SimpleLimitExceptionHandler有限制 属性和应与当前异常进行比较的异常类型。都 所提供类型的子类也被计算在内。给定类型的例外情况是 在达到限制之前忽略,然后重新抛出它们。其他类型的例外情况 总是被重新抛出。spring-doc.cadn.net.cn

重要的可选属性SimpleLimitExceptionHandler是布尔标志 叫useParent.是的false默认情况下,因此限制仅在 当前RepeatContext.当设置为true,则限制在 嵌套迭代(例如步骤中的一组块)。spring-doc.cadn.net.cn

听众

通常,能够接收针对跨领域问题的额外回调很有用 跨越许多不同的迭代。为此,Spring Batch 提供了RepeatListener接口。这RepeatTemplate允许用户注册RepeatListener实现,并且它们会被赋予带有RepeatContextRepeatStatus(在迭代期间可用)。spring-doc.cadn.net.cn

RepeatListener接口具有以下定义:spring-doc.cadn.net.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);
}

openclose回调在整个迭代之前和之后出现。before,afteronError适用于个人RepeatCallback调用。spring-doc.cadn.net.cn

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

并行处理

实现RepeatOperations不限于执行回调 顺序。非常重要的是,某些实现能够执行其 并行回调。为此,Spring Batch 提供了TaskExecutorRepeatTemplate,它使用 SpringTaskExecutor策略来运行RepeatCallback.默认情况下,使用SynchronousTaskExecutor,这有效果 在同一线程中执行整个迭代(与普通线程相同RepeatTemplate).spring-doc.cadn.net.cn

声明式迭代

有时,有些业务处理您知道您每次都想重复 它发生了。这方面的典型示例是消息管道的优化。 如果一批消息频繁到达,则处理它们比处理它们更有效 承担每条消息的单独事务费用。Spring Batch 提供 AOP 将方法调用包装在RepeatOperations对象 目的。这RepeatOperationsInterceptor执行截获的方法并重复 根据CompletionPolicy在提供的RepeatTemplate.spring-doc.cadn.net.cn

以下示例显示了使用 Spring AOP 命名空间的声明式迭代来 重复对名为processMessage(有关如何作的更多详细信息 配置 AOP 拦截器,请参阅 <<https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop,Spring 用户指南>>):spring-doc.cadn.net.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 配置来 重复对名为processMessage(有关如何作的更多详细信息 配置 AOP 拦截器,请参阅 <<https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop,Spring 用户指南>>):spring-doc.cadn.net.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;
}

前面的示例使用默认的RepeatTemplate拦截器内部。更改 策略、侦听器和其他详细信息,您可以注入RepeatTemplate进入拦截器。spring-doc.cadn.net.cn

如果截获的方法返回void,拦截器总是返回RepeatStatus.CONTINUABLE(因此,如果CompletionPolicy没有有限的终点)。否则,它返回RepeatStatus.CONTINUABLE直到截获方法的返回值为null. 此时,它返回RepeatStatus.FINISHED.因此,业务逻辑 在目标方法内部可以通过返回来表示没有更多工作可做null或者通过抛出由ExceptionHandler在提供的RepeatTemplate.spring-doc.cadn.net.cn