Spring Batch条件流创建无限循环 [英] Spring batch conditional flow creates infinite loop

查看:15
本文介绍了Spring Batch条件流创建无限循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的3步流:

public Job myJob() {
    Step extract = extractorStep();
    Step process = filesProcessStep();
    Step cleanup = cleanupStep();

    return jobBuilderFactory.get("my-job")
          .flow(echo("Starting job"))
          .next(extract)
          .next(process)
          .next(cleanup)
          .next(echo("Ending job"))
          .end()
          .build();
  }
现在,我想从StepExecutionListener.AfterStep()使用ExitStatus添加错误处理。任何错误都应将流转发到清理步骤。所以我改成了下面的代码:

 public Job myJob() {
    Step extract = extractorStep();
    Step process = filesProcessStep();
    Step cleanup = cleanupStep();

    return jobBuilderFactory.get("my-job")
          .start(echo("Starting batch job"))

          .next(extract).on(ExitStatus.FAILED.getExitCode()).to(cleanup)
          .from(extract).on("*").to(process)

          .next(process).on(ExitStatus.FAILED.getExitCode()).to(cleanup)
          .from(process).on("*").to(cleanup)

          .next(echo("End batch job"))
          .end()
          .build();
  }

现在我对清理步骤有一个无限循环。 我需要一些帮助来纠正此流程。

推荐答案

在您的示例中,从cleanup开始的流是未定义的。您应该使用.from(cleanup).to(echo("End batch job")).end()精确地确定流必须从cleanup继续到echo。下面是一个示例:

import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableBatchProcessing
public class MyJob {

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory steps;

    @Bean
    public Step extractorStep() {
        return steps.get("extractorStep")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("extractorStep");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public Step filesProcessStep() {
        return steps.get("filesProcessStep")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("filesProcessStep");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public Step cleanupStep() {
        return steps.get("cleanupStep")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("cleanupStep");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    public Step echo(String message) {
        return steps.get("echo-" + message)
                .tasklet((contribution, chunkContext) -> {
                    System.out.println(message);
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public Job job() {
        Step start = echo("Starting batch job");
        Step extract = extractorStep();
        Step process = filesProcessStep();
        Step cleanup = cleanupStep();
        Step stop = echo("End batch job");

        return jobs.get("job")
                .start(start).on("*").to(extract)

                    .from(extract).on(ExitStatus.FAILED.getExitCode()).to(cleanup)
                    .from(extract).on("*").to(process)

                    .from(process).on("*").to(cleanup)

                    .from(cleanup).next(stop)
                    .build()

                .build();
    }

    public static void main(String[] args) throws Exception {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyJob.class);
        JobLauncher jobLauncher = context.getBean(JobLauncher.class);
        Job job = context.getBean(Job.class);
        jobLauncher.run(job, new JobParameters());
    }

}

打印:

Starting batch job
extractorStep
filesProcessStep
cleanupStep
End batch job

如果extractorStep失败,例如:

@Bean
public Step extractorStep() {
    return steps.get("extractorStep")
            .tasklet((contribution, chunkContext) -> {
                System.out.println("extractorStep");
                chunkContext.getStepContext().getStepExecution().setExitStatus(ExitStatus.FAILED);
                return RepeatStatus.FINISHED;
            })
            .build();
}

该流将跳过filesProcessStep并转到清理:

Starting batch job
extractorStep
cleanupStep
End batch job

希望这对您有帮助。

这篇关于Spring Batch条件流创建无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆