引言
接着上篇:Spring Batch 批处理-作业增量参数,了解作业参数增量器后,本篇就来了解一下Spirng Batch 作业监听器,看能玩出啥花样。
作业监听器
Spring Batch 步骤/作业的设计延续Spring传统设计模式,加入生命周期的概念,也就是说,步骤/作业也有执行前,执行中,执行后3个时间概念
-
执行前:一般用于初始化操作, 步骤/作业执行前需要着手准备工作,比如:各种连接建立,线程池初始化等。
-
执行中:步骤/业务操作业务逻辑
-
执行后:步骤/业务执行完后,需要做各种清理动作,比如释放资源等。
Spring Batch 引入监听器的概念来实现生命周期逻辑,JobExecutionListener接口监听作业的生命周期,StepListener接口实现步骤的生命周期,当前先讲作业的监听器JobExecutionListener,后面Step对象章节我们再讲StepListener
public interface JobExecutionListener {
//作业执行前
void beforeJob(JobExecution jobExecution);
//作业执行后
void afterJob(JobExecution jobExecution);
}
需求:记录作业执行前,执行中,与执行后的状态
方式一:接口方式
//作业状态--接口方式
public class JobStateListener implements JobExecutionListener {
//作业执行前
@Override
public void beforeJob(JobExecution jobExecution) {
System.err.println("执行前-status:" + jobExecution.getStatus());
}
//作业执行后
@Override
public void afterJob(JobExecution jobExecution) {
System.err.println("执行后-status:" + jobExecution.getStatus());
}
}
定义JobStateListener 实现JobExecutionListener 接口,重写beforeJob,afterJob 2个方法。
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@EnableBatchProcessing
public class StatusListenerJob {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean
public Tasklet tasklet(){
return new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
JobExecution jobExecution = contribution.getStepExecution().getJobExecution();
System.err.println("执行中-status:" + jobExecution.getStatus());
return RepeatStatus.FINISHED;
}
};
}
//状态监听器
@Bean
public JobStateListener jobStateListener(){
return new JobStateListener();
}
@Bean
public Step step1(){
return stepBuilderFactory.get("step1")
.tasklet(tasklet())
.build();
}
@Bean
public Job job(){
return jobBuilderFactory.get("status-listener-job")
.start(step1())
.listener(jobStateListener()) //设置状态监听器
.build();
}
public static void main(String[] args) {
SpringApplication.run(StatusListenerJob.class, args);
}
}
新加jobStateListener()实例方法创建对象交个Spring容器管理,修改job()方法,添加.listener(jobStateListener()) 状态监听器,直接执行,观察结果
方式二:注解方式
除去上面通过实现接口方式实现监听之外,也可以使用@BeforeJob @AfterJob 2个注解实现
//作业状态--注解方式
public class JobStateAnnoListener {
@BeforeJob
public void beforeJob(JobExecution jobExecution) {
System.err.println("执行前-anno-status:" + jobExecution.getStatus());
}
@AfterJob
public void afterJob(JobExecution jobExecution) {
System.err.println("执行后-anno-status:" + jobExecution.getStatus());
}
}
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.listener.JobListenerFactoryBean;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@EnableBatchProcessing
public class StatusListenerJob {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean
public Tasklet tasklet(){
return new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
JobExecution jobExecution = contribution.getStepExecution().getJobExecution();
System.err.println("执行中-anno-status:" + jobExecution.getStatus());
return RepeatStatus.FINISHED;
}
};
}
//状态监听器
/* @Bean
public JobStateListener jobStateListener(){
return new JobStateListener();
}*/
@Bean
public Step step1(){
return stepBuilderFactory.get("step1")
.tasklet(tasklet())
.build();
}
@Bean
public Job job(){
return jobBuilderFactory.get("status-listener-job1")
.start(step1())
.incrementer(new RunIdIncrementer())
//.listener(jobStateListener()) //设置状态监听器
.listener(JobListenerFactoryBean.getListener(new JobStateAnnoListener()))
.build();
}
public static void main(String[] args) {
SpringApplication.run(StatusListenerJob.class, args);
}
}
修改job()方法,添加.listener(JobListenerFactoryBean.getListener(new JobStateAnnoListener()))状态监听器,直接执行,观察结果
不需要纠结那一长串方法是啥逻辑,只需要知道它能将指定监听器对象加载到spring容器中。