1

根据 Spring-Batch 文档(http://docs.spring.io/spring-batch/2.2.x/reference/html/configureStep.html#controllingStepFlow),在 xml 配置文件中控制步骤流程非常简单:

例如,我可以编写以下作业配置:

<job id="myJob">
    <step id="step1">
        <fail on="CUSTOM_EXIT_STATUS"/>
        <next on="*" to="step2"/>
    </step>

    <step id="step2">
        <end on="1ST_EXIT_STATUS"/>
        <next on="2ND_EXIT_STATUS" to="step10"/>
        <next on="*" to="step20"/>
    </step>

    <step id="step10" next="step11" />
    <step id="step11" />

    <step id="step20" next="step21" />
    <step id="step21" next="step22" />
    <step id="step22" />
</job>

有没有一种简单的方法以 java-config 方式定义这样的作业配置?(使用 JobBuilderFactory 等等...)

4

2 回答 2

4

正如文档还提到的,我们只能根据步骤的退出状态对流程进行分支。为了能够报告自定义退出状态(可能不同于从批处理状态自动映射的退出状态),我们必须afterStepStepExecutionListener.

假设我们有一个初始步骤step1(一个Tasklet类的实例Step1),我们想要执行以下操作:

  • 如果step1失败(例如通过抛出运行时异常),那么整个作业应该被视为FAILED.
  • 如果step1完成时退出状态为COMPLETED-WITH-A,那么我们想要分支到某个step2a应该处理这种特定情况的步骤。
  • 否则,我们留在工作的主卡车上并继续 step step2

现在,afterStep在类中提供一个方法Step1(也实现StepExecutionListener):

private static class Step1 implements Tasklet, StepExecutionListener
{
    @Override
    public ExitStatus afterStep(StepExecution stepExecution)
    {
        logger.info("*after-step1* step-execution={}", stepExecution.toString());

        // Report a different exit-status on a random manner (just a demo!).
        // Some of these exit statuses (COMPLETED-WITH-A) are Step1-specific 
        // and are used to base a conditional flow on them.

        ExitStatus exitStatus = stepExecution.getExitStatus();
        if (!"FAILED".equals(exitStatus.getExitCode())) {
            double r = Math.random(); 
            if (r < 0.50)
                exitStatus = null; // i.e. COMPLETED
            else 
                exitStatus = new ExitStatus(
                    "COMPLETED-WITH-A", 
                    "Completed with some special condition A");
        }
        logger.info("*after-step1* reporting exit-status of {}", exitStatus);
        return exitStatus;
    }

    // .... other methods of Step1
}

createJob最后,在我们JobFactory实现的方法内部构建工作流程:

@Override
public Job createJob()
{
    // Assume some factories returning instances of our Tasklets
    Step step1 = step1(); 
    Step step2a = step2a();
    Step step2 = step2();

    JobBuilder jobBuilder = jobBuilderFactory.get(JOB_NAME)
        .incrementer(new RunIdIncrementer())
        .listener(listener);  // a job-level listener

    // Build job flow
    return jobBuilder
        .start(step1)
            .on("FAILED").fail()
        .from(step1)
            .on("COMPLETED-WITH-A").to(step2a)
        .from(step1)
        .next(step2)
        .end()
        .build();
}
于 2017-09-14T00:51:51.537 回答
1

也许。如果您的意图是“以编程方式”(使用 SB 的框架接口,我的意思是)编写类似于流决策器的东西,那么有内置的实现,对于大多数用例来说已经足够了。

与 XML 配置相反,如果您熟悉JavaConfig注解,则可以使用它们;我个人更喜欢 XML 定义,但这只是个人意见。

于 2014-02-18T07:20:18.343 回答