在Spring Batch中重复步骤x次

时间:2015-03-26 18:57:02

标签: spring spring-batch

我正在使用配置了注释的Spring Batch 3.0.3创建一个批处理作业,该作业重复一个不确定次数的步骤。

我的第一步将在内存中读取重复步骤中使用的项目列表。我想重复一遍迭代这个作业范围的列表。

如何配置我的作业以运行相同的步骤x次?我在xml中看到了一个步骤,指定了下一步要运行的步骤。我想我可以在一个无限循环中指向彼此的两个步骤,直到列表被迭代。这会有效吗?有没有办法用注释做到这一点?下面是我的主要配置文件,其中一些代码无效。

@ComponentScan(excludeFilters = @Filter(IgnoreDuringScan.class))
@EnableAutoConfiguration
@EnableBatchProcessing
@Loggable
public class BatchCrudConfiguration
{
    @Bean
    public Job batchCRUDJob(JobBuilderFactory jobBuilderFactory, Step[] processSheetSteps)
    {
        JobBuilder jobBuilder = jobBuilderFactory.get("batchCRUDJob").incrementer(new RunIdIncrementer());
        FlowBuilder<FlowJobBuilder> jobFlowBuilder = jobBuilder.flow(processSheetSteps[0]);
        for (int i = 1; i < processSheetSteps.length; i++)
        {
            jobFlowBuilder = jobFlowBuilder.next(processSheetSteps[i]);
        }
        return jobFlowBuilder.end().build();
    }

    @Bean
    public Step[] processSheetSteps(
            StepBuilderFactory stepBuilderFactory,
            RawDataReader[] readers,
            DelegatingWriter writer,
            DelegatingProcessor processor,
            @Value("${batchcrud.chunkSize}") int chunkSize)
    {
        int numberOfReaders = readers.length;
        Step[] steps = new Step[numberOfReaders];
        for (int i = 0; i < numberOfReaders; i++)
        {
            steps[i] = stepBuilderFactory.get("processSheet" + i + "Step").<RawData, DataItem>
                    chunk(chunkSize).reader(readers[i]).processor(processor).writer(writer).build();
        }
        return steps;
    }

1 个答案:

答案 0 :(得分:8)

我接近这个的方法是通过以下方式:

  1. 第一步加载列表。
  2. 第二步处理列表中的项目。
  3. 第二步有StepExecutionListener,用于评估列表中是否有更多项目要处理。如果是这样,它将返回映射到同一步骤的ExitStatus。如果没有,它将返回ExitStatus映射以结束作业或继续作业(基于流程的其余部分)。
  4. 例如:

    StepExecutionListener

    public class MyListener {
    
        @Autowired
        private List myItems;
    
        @AfterStep
        public ExitStatus afterStep(StepExecution stepExecution) {
            if(myItems.size() > 0) {
                return new ExitStatus("CONTINUE");
            }
            else {
                return new ExitStatus("FINISHED");
            }
        }
    }
    

    作业配置

    ...
    @Bean
    public Step step1() {...}
    
    @Bean
    public MyListener listener() {..}
    
    @Bean
    public Step step2(MyListener listener) {
        return stepBuilder.get("step2")
                    .tasklet(myTasklet()) // Replace this piece as needed
                    .listener(listener).build();
    }
    
    @Bean
    public Job job1(Step step1, Step step2) {
        return jobBuilder.get("job1")
                         .start(step1)
                         .next(step2).on("CONTINUE").to(step2).on("FINISHED").end()
                         .build();
    }
    ...
    

    注意我没有测试过此代码,因此可能会出现拼写错误等。