在spring batch中主要以以下四种监听器为主:
- Step监听器 :监听step的执行开始和结束;
- Job监听器 :监听job的执行开始和结束;
- SkipListener监听器 :在读、处理、写的过程中,监听跳过的异常;
- ChunkListener监听器 :监听的chunk的执行开始和结束,或者监听chunk出错。
一、Step监听器
首先创建一个step监听器,实现StepExecutionListener 接口即可。
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepExecutionListener;
public class StepExecutionListenerExample implements StepExecutionListener {
/*在step之前运行*/
@Override
public void beforeStep(StepExecution paramStepExecution) {
System.out.println("Execution befor step……");
}
/*在step之后运行*/
@Override
public ExitStatus afterStep(StepExecution paramStepExecution) {
System.out.println("Execution after step……");
return ExitStatus.COMPLETED;
}
}
在step中添加监听器
@Configuration
public class ConfigBatch {
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Bean
public Step step1(){
Step step = stepBuilderFactory.get("step1")
.listener(new StepExecutionListenerExample()) //添加step监听器
.tasklet((stepContribution, chunkContext) -> { //tasklet中为执行的业务逻辑
System.out.println("step1 正在执行……");
return RepeatStatus.FINISHED;})
.allowStartIfComplete(true)
.build();
return step;
}
@Bean
public Job job1(){
Job job = jobBuilderFactory.get("job1")
.start(step1())
.build();
return job;
}
}
运行该Job作业,输出结果如下:
Execution befor step……
step1 正在执行……
Execution after step……
二、Job监听器
首先创建Job监听器
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;
public class JobExecutionListenerExample implements JobExecutionListener{
@Override
public void beforeJob(JobExecution paramJobExecution) {
System.out.println("Execution before Job……");
}
@Override
public void afterJob(JobExecution paramJobExecution) {
System.out.println("Execution after Job……");
}
}
在job中添加监听器
@Configuration
public class ConfigBatch {
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Bean
public Step step1(){
Step step = stepBuilderFactory.get("step1")
.listener(new StepExecutionListenerExample()) //添加step监听器
.tasklet((stepContribution, chunkContext) -> { //tasklet中为执行的业务逻辑
System.out.println("step1 正在执行……");
return RepeatStatus.FINISHED;})
.allowStartIfComplete(true)
.build();
return step;
}
@Bean
public Job job1(){
Job job = jobBuilderFactory.get("job1")
.listener(new JobExecutionListenerExample()) //添加job监听器
.start(step1())
.build();
return job;
}
}
三、SkipListener监听器
当在step中使用skip跳过指定异常时,触发SkipListener监听器。
首先定义一个SkipListener的实现类
public class SkipListenerExample implements SkipListener<Object, Object> {
/*读出错*/
@Override
public void onSkipInRead(Throwable paramThrowable) {
System.out.println("onSkipInRead");
}
/*写出错*/
@Override
public void onSkipInWrite(Object paramS, Throwable paramThrowable) {
System.out.println("paramS : " + paramS);
}
/*处理出错*/
@Override
public void onSkipInProcess(Object paramT, Throwable paramThrowable) {
System.out.println("paramT : " + paramT);
}
}
调用方式:
@Bean
public Step chunkStep() throws Exception{
return stepBuilderFactory.get("chunkStep")
.<User, User>chunk(1)
.reader(fileItemReader())
.processor(itemProcess())
.writer(list -> list.forEach(System.out::println))
.faultTolerant()
.skip(Exception.class) //跳过所有的异常
.skipLimit(3)
.allowStartIfComplete(true)
.listener(new SkipListenerExample())
.build();
}
监听器的定义也可以写成如下形式
public class SkipListenerExample{
/*读出错*/
@OnSkipInRead
public void onSkipInRead(Throwable paramThrowable) {
System.out.println("onSkipInRead");
}
/*写出错*/
@OnSkipInWrite
public void onSkipInWrite(Object paramS, Throwable paramThrowable) {
System.out.println("paramS : " + paramS);
}
/*处理出错*/
@OnSkipInProcess
public void onSkipInProcess(Object paramT, Throwable paramThrowable) {
System.out.println("paramT : " + paramT);
}
}
四、ChunkListener监听器
用于监听chunk的执行情况,每当chunk执行时,就触发监听器中的方法。
首先定义一个ChunkListener的监听器
public class ChunkListenerExample implements ChunkListener {
@Override
public void beforeChunk(ChunkContext paramChunkContext) {
System.out.println("beforeChunk……");
}
@Override
public void afterChunk(ChunkContext paramChunkContext) {
System.out.println("afterChunk……");
}
@Override
public void afterChunkError(ChunkContext paramChunkContext) {
System.out.println("afterChunkError……");
}
}
在step中调用方式
@Bean
public Step chunkStep() throws Exception{
return stepBuilderFactory.get("chunkStep")
.<User, User>chunk(1) //每4次提交一次
.reader(fileItemReader()) //读取文件,并把文件中每行数据映射到工程中的User bean中
.processor(itemProcess())
.writer(list -> list.forEach(System.out::println))
.allowStartIfComplete(true)
.listener(new ChunkListenerExample())
.build();
}
一旦chunk执行,就分别执行beforeChunk、afterChunk方法,如果有错误还要执行再执行afterChunkError方法。