How to terminate Step within a Spring Batch Split Flow with a Decider

僤鯓⒐⒋嵵緔 提交于 2019-12-09 03:43:48

问题


I've happened up the following design defect in Spring Batch.

  1. A Step must have a Next attribute unless it is the last Step or last Step of a Split Flow.
  2. A Decider block must handle all cases returned by the Decider.

Because of this, in a Split Flow, where the final Step would not have a Next attribute, if there is a Decider guarding it, then it must have a Next attribute. So it shouldn't have that attribute, but it also needs it. Catch 22.

Example:

<!-- Process parallel steps -->
<split id="split01">
    <flow>
        <step id="step1" next="step02">
            <!-- Do something -->
        </step>
        <step id="step02">
            <!-- Do something else -->
        </step>
    </flow>
    <flow>
        <step id="step03">
            <!-- Do something -->
        </step>

        <!-- Only run under specific conditions -->
        <decision id="decideToRunStep04" decider="isStepNeededDecider" >
            <next on="RUN" to="step04"/>
            <!-- Other state is "SKIP" -->
        </decision>
        <step id="step04">
            <!-- Conditionally do something-->
        </step>
    </flow>
</split>

<step id="step05" >
    <!-- Some more stuff -->
</step>

This seems like something the Spring guys would have thought of, so curious what the right, non-hack way to achieve this is. Thanks.


回答1:


Given no answers from anyone on this, I'll proffer the hack that I'm using. It's not pretty, but neither is Spring.

Create a No Op Tasklet to use in a No Op step.

public class NoopTasklet implements Tasklet {
    @Override
    public RepeatStatus execute(final StepContribution contribution,
            final ChunkContext chunkContext) throws Exception {
        return RepeatStatus.FINISHED;
    }
}

The add NOOP tasklet to the decision block from the original example

<!-- Does nothing -->
<bean id="noopTasklet" class="com.foo.NoopTasklet" />

<!-- From example in question
<decision id="decideToRunStep04" decider="isStepNeededDecider" >
    <next on="RUN" to="step04"/>
    <next on="SKIP" to="noop01"/>
</decision>
<step id="step04">
    <!-- Conditionally do something-->
</step>
<step id="noop01">
    <!-- Does nothing in the SKIP case
    <tasklet ref="noopTasklet" />
</step>



回答2:


Spring is the prettiest code in town. That said:

<step id="step1" parent="s1">
    <end on="FAILED" />
    <next on="COMPLETED WITH SKIPS" to="errorPrint1" />
    <next on="*" to="step2" />
</step>

as it is documented at http://docs.spring.io/spring-batch/reference/html/configureStep.html.




回答3:


In XML

<batch:decision id="customerDecision" decider="customerDecider">
            <batch:next on="FILE_FAILURE" to="fileFailureStep" />
            <batch:next on="FILE_GENERATION" to="loadData" /> 
</batch:decision>

In customerDecider class

public class CustomerDecider implements JobExecutionDecider {    
@Override
public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecutionStatus) {
If(x)
    return new FlowExecutionStatus("FILE_FAILURE") ;
else
    return new FlowExecutionStatus("FILE_GENERATION") ;
}
}


来源:https://stackoverflow.com/questions/21782008/how-to-terminate-step-within-a-spring-batch-split-flow-with-a-decider

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!