Spring Batch 任务完成后如何调用自定义 Writer 类中的指定方法?
结论
该需求完全可以实现,Spring Batch 提供了两种常用的实现方案,你可以根据业务场景选择:
前置改造
两种方案都需要先将你当前直接实例化的 NotaryWriter 改为 Spring 托管的 Bean,保证执行过程中的写入实例和后续调用 reset 方法的是同一个对象:
// 把NotaryWriter注册为Bean @Bean public NotaryWriter notaryWriter(WpService wpService){ return new NotaryWriter(wpService); } // 调整Step配置,使用容器托管的Writer @Bean public Step readNotaryListStep(){ return steps.get("readNotaryListStep"). <Integer,Integer>chunk(1) .reader(serviceItemReader()) .processor(new NotaryDetailsEnrichProcessor(notaryService)) .writer(notaryWriter(wpService)) // 改这里,用上面定义的Bean .build(); }
方案1:使用Job执行监听器(JobExecutionListener)
适合 resetCounter 是纯清理类的辅助逻辑,不需要作为正式业务步骤记录执行状态的场景:
- 给Job配置添加执行监听器,在Job执行完成后的回调中调用reset方法,你可以自行添加逻辑判断仅在Job执行成功时才触发重置:
@Bean(name="updateNotaryListInfoJob") public Job updateNotaryListInfoJob(NotaryWriter notaryWriter){ return jobs.get("updateNotaryListInfoJob") .incrementer(new RunIdIncrementer()) .start(readNotaryListStep()) // 添加Job执行监听器 .listener(new JobExecutionListener() { @Override public void beforeJob(JobExecution jobExecution) { // 无前置逻辑可留空 } @Override public void afterJob(JobExecution jobExecution) { // 可选:仅当Job执行成功时才重置计数器 if(jobExecution.getStatus() == BatchStatus.COMPLETED){ notaryWriter.resetCounter(); } // 如果不管Job成功失败都要重置,去掉上面的if判断即可 } }) .build(); }
方案2:新增独立的Tasklet收尾步骤
适合 resetCounter 属于业务流程的必要环节,需要记录该步骤的执行状态、执行失败时标记整个Job失败的场景:
- 新增一个专门用于重置计数器的Tasklet步骤:
@Bean public Step resetCounterStep(NotaryWriter notaryWriter){ return steps.get("resetCounterStep") .tasklet((contribution, chunkContext) -> { notaryWriter.resetCounter(); return RepeatStatus.FINISHED; }) .build(); }
- 调整Job配置,把重置步骤加到原有步骤之后:
@Bean(name="updateNotaryListInfoJob") public Job updateNotaryListInfoJob(){ return jobs.get("updateNotaryListInfoJob") .incrementer(new RunIdIncrementer()) .start(readNotaryListStep()) .next(resetCounterStep()) // 加这行,执行完原有步骤后执行重置 .build(); }
注意事项
如果你的 NotaryWriter 里的计数器是成员变量,务必保证它是单例的,默认Spring Bean的作用域就是单例,只要你按上面的方式把它交给容器管理就不会有问题。
内容的提问来源于stack exchange,提问作者AndreaNobili
相关产品推荐
相关产品推荐

