Java 返回到Spring批处理中的上一步
我想使用Spring批处理实现类似于以下作业的作业:Java 返回到Spring批处理中的上一步,java,spring,spring-batch,Java,Spring,Spring Batch,我想使用Spring批处理实现类似于以下作业的作业: Step1 -----> Step2 --> End ^ | | | ------------ 在步骤2中的某些情况下,由步骤2的自定义ExitCode确定,要么重新启动步骤1,然后再次启动步骤2,要么处理将结束 我想象的是这样的: return jobBuilderFactory.get("jobName").incrementer(new RunIdIncrement
Step1 -----> Step2 --> End
^ |
| |
------------
在步骤2中的某些情况下,由步骤2的自定义ExitCode确定,要么重新启动步骤1,然后再次启动步骤2,要么处理将结束
我想象的是这样的:
return jobBuilderFactory.get("jobName").incrementer(new RunIdIncrementer())
.start(step1()).next(step2())
.on("condition1").end()
.from(step1())
.on("condition2").to(step1()).end().build();
但是很明显,在通过步骤2的条件2处理步骤1之后,步骤2将不会再次启动
如何实现这种递归批处理
编辑:我设法找到了一个解决方案,但是,我还不知道这是否是一个肮脏的解决方案,因为它似乎非常简单:
jobBuilderFactory.get("jobName")
.flow(step1())
.next(step2())
.on("launchStep1Again")
.to(step1())
.from(step2())
.on("endJobExecution")
.end().build().build();
因此,从使用Fluent API的.start()方法到其.flow()方法的简单更改似乎可以达到目的。我认为您可以扩展StepExecutionListenerSupport类并修改配置,如下所示:
<step id="step1" next="step2">
<tasklet ref="step1Tasklet" allow-start-if-complete="true"/>
</step>
<step id="step2">
<tasklet ref="step2Tasklet"/>
<listeners>
<listener ref="myListener"/>
</listeners>
<next on="Back" to="step1"/>
</step>
public class MyListener extends StepExecutionListenerSupport {
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
if(wantToLoop) {
return new ExitStatus("Back");
} else {
return stepExecution.getExitStatus();
}
}
}
公共类MyListener扩展了StepExecutionListener支持{
@凌驾
公共出口状态后步骤(步骤执行步骤执行){
如果(wantToLoop){
返回新的退出状态(“返回”);
}否则{
返回stepExecution.getExitStatus();
}
}
}
SpringBatch不用于处理递归循环。虽然您可以绕过它,但在出现故障和重新启动时,您将遇到问题
SpringBatch将一个步骤的读写器的当前“位置”存储在其执行上下文中;为了能够在上次崩溃的位置重新启动作业
因此,在重新启动作业的情况下,SpringBatch将假定这是作业的第一次执行
根据你的工作结构,这可能不是问题,但你必须记住这一点
在我看来,更好的解决方案是在处理起始作业的单独类中实现在作业外部处理循环
以下两个问题的答案可能有助于找到此类解决方案:
我很清楚决策过程,但我想知道的是,如何回到某一步,并从该步开始继续流程。据我所知,您上面提供的XML配置将在ExitStatus“Back”上启动step1,然后,由于“next”属性,将启动step2,这是所需的解决方案。但在我的Java配置中,对于相同的步骤,情况并非如此,是吗?对于XML配置,“next”属性与步骤相关,而对于Java配置,它与流相关,不是吗?