当我的 Spring 批处理作业完成时,如何调用编写器 class 的方法?

How can I call a method of the writer class when my Spring Batch Job complete?

我正在开发 Spring 批处理应用程序,但遇到以下问题。

我定义了包含此步骤的单步作业:

@Bean
public Step readNotaryListStep(){
    return steps.get("readNotaryListStep").
            <Integer,Integer>chunk(1)  
            .reader(serviceItemReader())
            .processor(new NotaryDetailsEnrichProcessor(notaryService))
            .writer(new NotaryWriter(wpService))
            .build();
}

@Bean(name="updateNotaryListInfoJob")
public Job updateNotaryListInfoJob(){
    return jobs.get("updateNotaryListInfoJob")
            .incrementer(new RunIdIncrementer())
            .start(readNotaryListStep())
            .build();
}

它工作正常。基本上它是从 reader 读取,输出经过处理,最后由我为编写器创建的 new NotaryWriter(wpService) 写入。

好的...现在出现了以下需求:作业完成后,我需要调用一个名为 resetCounter() 的方法,该方法定义到我的 NotaryWriter 中 class(为我的步骤的作者部分设置的 class)。

是否可以实现这样的行为?万一我该如何实现呢?

您可以实施 JobExecutionListener 甚至 StepExecutionListener,这允许您在作业和步骤完成时添加回调。它们都可以通过 JobBuilderStepBuilder 上的 listener() 配置。

要允许 JobExecutionListener 在步骤中配置的 NotaryWriter 的同一实例上调用方法,您必须将 NotaryWriter 作为 spring bean 而不是手动创建它,并确保 JobExecutionListener 和步骤都引用它。

喜欢的东西:

@Bean
public NotaryWriter notaryWriter(){
    return new NotaryWriter(wpService);
}

并将其注入 JobExecutionListenerStep :

@Component
public MyJobExecutionListener implements JobExecutionListener {
    
    @Autowired
    private NotaryWriter notaryWriter;

    public void beforeJob(JobExecution jobExecution){

    }

    public void afterJob(JobExecution jobExecution){
        notaryWriter.resetCounter();
    }
}

@Bean
public Step readNotaryListStep(NotaryWriter notaryWriter){
    return steps.get("readNotaryListStep").
            .........
            .writer(notaryWriter)
            .build();
}

我只是向您展示了大概的想法。您必须根据要执行的操作来考虑 JobExecutionListenerNotaryWriter 的范围。它支持开箱即用的作业范围、步骤范围或仅应用程序范围。

因为在我看来你实际上希望每个步骤都有自己的 NotaryWriter 实例,这样它的计数器就不会相互混淆。如果是,您可以简单地将其定义为 @StepScope 并且不需要任何侦听器:

@Bean
@StepScope
public NotaryWriter notaryWriter(){
    return new NotaryWriter(wpService);
}

@Bean
public Step readNotaryListStep(NotaryWriter notaryWriter){
    return steps.get("readNotaryListStep").
            .........
            .writer(notaryWriter)
            .build();
}