Spring Batch:如何触发AsyncItemProcessor委托类的StepExecutionListener方法?
解决AsyncItemProcessor委托类的StepExecutionListener方法不被调用的问题
当使用AsyncItemProcessor时,如果其委托的ItemProcessor同时实现了StepExecutionListener接口,默认情况下该委托类的beforeStep()和afterStep()方法不会被触发——这是因为AsyncItemProcessor本身并未自动将步骤生命周期事件转发给内部的委托处理器。
可以通过以下两种方式解决这个问题:
方法一:直接将委托类注册为Step监听器
在配置Step时,直接把实现了StepExecutionListener的委托ItemProcessor注册为Step的监听器,Spring Batch会直接在步骤生命周期中调用它的监听器方法,不受AsyncItemProcessor的包装影响。
示例配置代码:
@Bean public Step myStep(JobRepository jobRepository, PlatformTransactionManager transactionManager, AsyncItemProcessor asyncProcessor, ItemWriter<Output> writer, ItemProcessor<Input, Output> delegateProcessor) { return new StepBuilder("myStep", jobRepository) .<Input, Output>chunk(10, transactionManager) .reader(itemReader()) .processor(asyncProcessor) .writer(writer) .listener(delegateProcessor) // 注册委托类为Step监听器 .build(); }
方法二:让AsyncItemProcessor转发监听器方法调用
自定义AsyncItemProcessor的实现,让它同时实现StepExecutionListener接口,并在对应的方法中调用委托类的监听器方法(如果委托类是StepExecutionListener的实例),再将这个AsyncItemProcessor注册为Step监听器。
示例配置代码:
@Bean public AsyncItemProcessor<Input, Output> processor(ItemProcessor<Input, Output> itemProcessor, TaskExecutor taskExecutor) { // 创建AsyncItemProcessor的匿名子类,实现StepExecutionListener接口 AsyncItemProcessor<Input, Output> asyncItemProcessor = new AsyncItemProcessor<>() { @Override public void beforeStep(StepExecution stepExecution) { // 检查委托类是否为StepExecutionListener,若是则调用beforeStep if (getDelegate() instanceof StepExecutionListener) { ((StepExecutionListener) getDelegate()).beforeStep(stepExecution); } } @Override public ExitStatus afterStep(StepExecution stepExecution) { // 检查委托类是否为StepExecutionListener,若是则调用afterStep并返回结果 if (getDelegate() instanceof StepExecutionListener) { return ((StepExecutionListener) getDelegate()).afterStep(stepExecution); } return null; } }; asyncItemProcessor.setTaskExecutor(taskExecutor); asyncItemProcessor.setDelegate(itemProcessor); return asyncItemProcessor; } // 配置Step时将自定义的AsyncItemProcessor注册为监听器 @Bean public Step myStep(JobRepository jobRepository, PlatformTransactionManager transactionManager, AsyncItemProcessor<Input, Output> asyncProcessor, ItemWriter<Output> writer) { return new StepBuilder("myStep", jobRepository) .<Input, Output>chunk(10, transactionManager) .reader(itemReader()) .processor(asyncProcessor) .writer(writer) .listener(asyncProcessor) // 注册AsyncItemProcessor为Step监听器 .build(); }
两种方法都能确保委托类的StepExecutionListener方法在步骤的正确时机被调用,可根据实际场景选择合适的实现方式。
内容的提问来源于stack exchange,提问作者ALAN PAINTER
相关产品推荐
相关产品推荐

