如何更新 spring-batch Tasklet 中的项目数?

How to update item count in spring-batch Tasklet?

我想创建一个通用的 StepExecutionListener。它应该记录 Tasklet 步骤处理的项目数。

问题:计数没有自动更新。所以我可能必须在 Tasklet.execute() 的某处执行此操作。但是怎么办?

    @Bean
    @JobScope
    public Tasklet myTasklet() {
        return new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                int count = dao.deleteByName(name);
                //TODO how to set the count into the stepExecution context?
                return RepeatStatus.FINISHED;
            }
        };
    }

    @Bean
    public Step myStep() {
        return getStepBuilderFactory().get("myStep")
                .listener(new StepListener())
                .tasklet(myTasklet())
                .build();
    }


public class StepListener extends StepExecutionListenerSupport {
    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        long items = stepExecution.getWriteCount();
        logger.info("items processed in tasklet: " + items);
        return super.afterStep(stepExecution);
    }
}

contribution.incrementWriteCount() 可能是要走的路

@Bean
@JobScope
public Tasklet myTasklet() {
    return new Tasklet() {
        @Override
        public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
            int count = dao.deleteByName(name);
            contribution.incrementWriteCount(count); // <--
            return RepeatStatus.FINISHED;
        }
    };
}

您可以使用 stepExecution = chunkContext.getStepContext().getStepExecution() 从您的 execute() 获得 StepExecution。您应该在您的 Tasklet 中设置 stepExecutionContext 以防止在每次执行时都使用 get 方法(这可能代价高昂,因为我不认为这些是简单的 getter)。

您现在可以在 execute() 中使用 stepExecution.setLong("yourWriteCount", count) 操作 stepExecution 的内部变量,同样可以获取它。 (如果是自定义tasklet也没关系,同样的规则适用)。

在监听器中,可以通过executionContext参数得到yourWriteCount,同理

通常 executionContext 在整个步骤中都是相同的。