首页 > 解决方案 > 如何在 Spring Batch 的委托 ItemReader 中获取 StepExecution

问题描述

我创建了执行块处理的批处理应用程序。我正在使用完成策略创建块。

以下是我的批处理配置,(保持代码最少,如果需要其他信息请告诉我)

@Bean
public Job myJob() {
    ItemReader itemReader = itemReader();
    return jobBuilder.get("job").start(myStep(itemReader, completionPolicyReader(itemReader), writer(), processor()));
}

@Bean
public Step myStep(ItemReader itemReader, MyCompletionPolicy completionPolicyReader, ItemWriter writer, ItemProcessor processor) {
    return stepBuilder.get("step").chunk(completionPolicyReader).reader(completionPolicyReader).processor(processor).writer(writer).listener(itemReader).build(); // registered delegated itemReader to listener.
}

@Bean
public MyCompletionPolicy completionPolicyReader(ItemReader itemReader) {
    MyCompletionPolicy obj = new MyCompletionPolicy();
    obj.setDelegate(itemReader);
    return obj;
}

@Bean
public ItemReader itemReader() {
   abc === xyz ? new AReader() : new BReader();
}
// other config

以下是我的MyCompletionPolicy哪个代表实际,即ItemReader根据某些条件。AReaderBReader

class MyCompletionPolicy extends
    CompletionPolicySupport implements ItemReader<MyModel>, StepExecutionListener {

    public void setDelegate(ItemReader<MyModel> itemReader) {
      this.itemReader = itemReader;
      this.delegate = new SingleItemPeekableItemReader<MyModel>();
      this.delegate.setDelegate(itemReader);
    }

    @Override
    public MyModel read() {
      currentReadItem = delegate.read(); // Here I am delegating to actual reader (ex AReader) where I cannot get `StepExecution`
      return currentReadItem;
    }

   .... // Other overridden methods
}

以下是我AReader无法到达的地方StepExecution

class AReader  implements ItemReader<MyModel>, StepExecutionListener {
    @Override
    public void beforeStep(StepExecution stepExecution) {
       // stepExecution is NULL
    }
    .... // other overridden methods
}

如何在我的委托 ItemReader 中获取 stepExecution,即在 AReader 中。

======编辑=====

关于最佳实践的子问题。如果我想增加块之间的计数,例如在 ItemReader 的多次调用之间,并在 ItemReader 中使用计数器的当前值。在 ItemReader 类中创建类字段是一种好习惯,还是应该将其存储在 ExecutionContext 中?

  1. 考虑单线程应用程序
  2. 考虑多线程应用程序

标签: springspring-bootspring-batch

解决方案


默认情况下,Spring Batch 会自动将您的读取器/处理器/写入器注册为侦听器(如果它们实现了StepExecutionListener. 在您的情况下,阅读器MyCompletionPolicy将实现StepExecutionListener并将自动注册为侦听器。

但是,Spring Batch 不知道您的MyCompletionPolicy委托给另一个阅读器,因此您需要在步骤中将您的委托显式注册为侦听器。


推荐阅读