首页 > 解决方案 > Spring Batch:CompositeItemWriter、@BeforeStep 和控制 StepExecution

问题描述

我最近偶然发现了一个春季批次的非常扭曲的问题。要求如下:

我有两个主要步骤:

从设计的角度来看,第一步看起来像这样:

    @Bean
    public Step myFirstStep(JdbcCursorItemReader<Revision> reader) {

        return stepBuilderFactory.get("my-first-step")
            .<Revision, Revision>chunk(1)
            .reader(readerRevisionNumber)
            .writer(compositeItemWriter())
            .listener(executionContextPromotionListener())
            .build();

复合项目编写器:

    @Bean
    public CompositeItemWriter<Revision> compositeItemWriter() {
        CompositeItemWriter writer = new CompositeItemWriter();
        writer.setDelegates(Arrays.asList(somewriter(), someOtherwriter(), aWriterThatIsSupposedToPassDataToAnotherStep()));
        return writer;
    }

虽然前两位作者并不复杂,但我的兴趣集中在第三位。

aWriterThatIsSupposedToPassDataToAnotherStep()

正如您可能已经猜到的那样,这将用于获取之前正在处理的一些数据,以便在我的第二步中推广它:

@Component
@StepScope
public class AWriterThatIsSupposedToPassDataToAnotherStep implements ItemWriter<SomeEntity> {

    private StepExecution stepExecution;

    public void write(List<? extends SomeEntity> items) {

        ExecutionContext stepContext = this.stepExecution.getExecutionContext();
        stepContext.put("revisionNumber", items.stream().findFirst().get().getSomeField());
        System.out.println("writing : " + items.stream().findFirst().get().getSomeField()+ "to ExecutionContext");
    }

    @BeforeStep
    public void saveStepExecution(StepExecution stepExecution) {
        this.stepExecution = stepExecution;
    }

}

问题是:只要这个作家是复合作家列表的一部分(如上所述)我最后一个作家的@BeforeStep 永远不会被执行,这最终导致我无法将我的信息传输到执行上下文。在步骤定义中用我的单个“AWriterThatIsSupposedToPassDataToAnotherStep”替换我的 CompositeItemWriter 时,它会正确执行。

它是否与某种申报令或其他东西有关?

非常感谢进一步的帮助。

标签: spring-batch

解决方案


找到了解决方案(在我的一些同事的帮助下),并来自:https ://stackoverflow.com/a/39698653/1957764

您需要将编写器声明为复合编写器的一部分和一个步骤侦听器,以使其执行@BeforeStep 注释方法。


推荐阅读