当我的 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
,这允许您在作业和步骤完成时添加回调。它们都可以通过 JobBuilder
和 StepBuilder
上的 listener()
配置。
要允许 JobExecutionListener
在步骤中配置的 NotaryWriter
的同一实例上调用方法,您必须将 NotaryWriter
作为 spring bean 而不是手动创建它,并确保 JobExecutionListener
和步骤都引用它。
喜欢的东西:
@Bean
public NotaryWriter notaryWriter(){
return new NotaryWriter(wpService);
}
并将其注入 JobExecutionListener
和 Step
:
@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();
}
我只是向您展示了大概的想法。您必须根据要执行的操作来考虑 JobExecutionListener
和 NotaryWriter
的范围。它支持开箱即用的作业范围、步骤范围或仅应用程序范围。
因为在我看来你实际上希望每个步骤都有自己的 NotaryWriter
实例,这样它的计数器就不会相互混淆。如果是,您可以简单地将其定义为 @StepScope
并且不需要任何侦听器:
@Bean
@StepScope
public NotaryWriter notaryWriter(){
return new NotaryWriter(wpService);
}
@Bean
public Step readNotaryListStep(NotaryWriter notaryWriter){
return steps.get("readNotaryListStep").
.........
.writer(notaryWriter)
.build();
}
我正在开发 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
,这允许您在作业和步骤完成时添加回调。它们都可以通过 JobBuilder
和 StepBuilder
上的 listener()
配置。
要允许 JobExecutionListener
在步骤中配置的 NotaryWriter
的同一实例上调用方法,您必须将 NotaryWriter
作为 spring bean 而不是手动创建它,并确保 JobExecutionListener
和步骤都引用它。
喜欢的东西:
@Bean
public NotaryWriter notaryWriter(){
return new NotaryWriter(wpService);
}
并将其注入 JobExecutionListener
和 Step
:
@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();
}
我只是向您展示了大概的想法。您必须根据要执行的操作来考虑 JobExecutionListener
和 NotaryWriter
的范围。它支持开箱即用的作业范围、步骤范围或仅应用程序范围。
因为在我看来你实际上希望每个步骤都有自己的 NotaryWriter
实例,这样它的计数器就不会相互混淆。如果是,您可以简单地将其定义为 @StepScope
并且不需要任何侦听器:
@Bean
@StepScope
public NotaryWriter notaryWriter(){
return new NotaryWriter(wpService);
}
@Bean
public Step readNotaryListStep(NotaryWriter notaryWriter){
return steps.get("readNotaryListStep").
.........
.writer(notaryWriter)
.build();
}