一、拦截器实现说明
1.拦截器实现的方式
Spring Batch项目实现Job级拦截器有两种方法:
(1)实现接口:org.springframework.batch.core.JobExecutionListener
public interface JobExecutionListener {
//Job执行之前调用该方法
void beforeJob(JobExecution var1);
//Job执行之后调用该方法
void afterJob(JobExecution var1);
}
(2)通过Annotation机制实现
- @BeforeJob
- @AfterJob
2.拦截器的配置
通过下面的方法配置拦截器:
<batch:job id="jobId">
<batch:step id="stepId">
. . . . . .
</batch:step>
<!--定义拦截器-->
<batch:listeners>
<batch:listener ref="listenerId"/>
</batch:listeners>
</batch:job>
<!--拦截器实现类-->
<bean id="listenerId" class="com.xj.demo3.MyJobExecutionListener"/>
3.拦截器异常
拦截器方法如果抛出异常会影响Job的正常执行,所以在执行自定义的拦截器时候,要考虑对拦截器发生的异常做处理,避免影响业务。如果拦截器发生异常,会导致Job执行的状态为“FAILED”。
4.拦截器执行顺序
在配置文件中可以配置多个listener,拦截器之间的执行顺序按照listener定义的顺序执行。before方法按照listener定义的顺序执行,after方法按照相反的顺序执行。(参考下面项目的运行结果)
二、拦截器项目实现
1.项目结构:
2.代码实现:
Demo3BatchMain.java:
package com.xj.demo3;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @Author : xjfu
* @Date : 2021/11/7 18:29
* @Description :
*/
public class Demo3BatchMain {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("demo3/job/demo3-job.xml");
//Spring Batch的作业启动器
JobLauncher launcher = (JobLauncher) context.getBean("jobLauncher");
//在demo3-jobContext.xml中配置一个作业
Job job = (Job) context.getBean("demo3TaskletJob");
try{
//开始执行这个作业,获得出来结果(要运行的job,job参数对象)
JobExecution result = launcher.run(job, new JobParameters());
System.out.println(result.toString());
}catch (Exception e){
e.printStackTrace();
}
}
}
MyAnnotationListener.java:
package com.xj.demo3;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.annotation.AfterJob;
import org.springframework.batch.core.annotation.BeforeJob;
/**
* @Author : xjfu
* @Date : 2021/11/7 18:57
* @Description :通过Annotation实现JobExecutionListener接口的拦截器
*/
public class MyAnnotationListener {
//Job执行之前调用该方法
@BeforeJob
public void beforeJob(JobExecution jobExecution){
System.out.println("MyAnnotationListener——before: create time:" + jobExecution.getCreateTime());
}
//Job执行之后调用该方法
@AfterJob
public void afterJob(JobExecution jobExecution){
System.out.println("MyAnnotationListener——after: create time:" + jobExecution.getCreateTime());
}
}
MyJobExecutionListener.java:
package com.xj.demo3;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;
/**
* @Author : xjfu
* @Date : 2021/11/7 18:53
* @Description :实现JobExecutionListener接口的拦截器
*/
public class MyJobExecutionListener implements JobExecutionListener {
//Job执行之前调用该方法
@Override
public void beforeJob(JobExecution jobExecution) {
System.out.println("MyJobExecutionListener——before: create time:" + jobExecution.getCreateTime());
}
//Job执行之后调用该方法
@Override
public void afterJob(JobExecution jobExecution) {
System.out.println("MyJobExecutionListener——after: create time:" + jobExecution.getCreateTime());
}
}
MyTasklet.java:
package com.xj.demo3;
import org.apache.commons.collections.bag.SynchronizedSortedBag;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
/**
* @Author : xjfu
* @Date : 2021/11/7 18:29
* @Description :
*/
public class MyTasklet implements Tasklet {
@Override
public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
System.out.println("This is a test for interceptor(拦截器)");
return RepeatStatus.FINISHED;
}
}
demo3-job.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:batch="http://www.springframework.org/schema/batch"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd">
<import resource="classpath:demo3/job/demo3-jobContext.xml"/>
<batch:job id="demo3TaskletJob">
<batch:step id="demo3Step">
<batch:tasklet ref="myTasklet"/>
</batch:step>
<!--定义两个拦截器-->
<batch:listeners>
<batch:listener ref="myJobExecutionListener"/>
<batch:listener ref="myAnnotationListener"/>
</batch:listeners>
</batch:job>
</beans>
demo3-jobContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"></bean>
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository"/>
</bean>
<!--定义MyTasklet类-->
<bean id="myTasklet" class="com.xj.demo3.MyTasklet"/>
<!--定义MyJobExecutionListener拦截器-->
<bean id="myJobExecutionListener" class="com.xj.demo3.MyJobExecutionListener"/>
<!--定义MyAnnotationListener拦截器-->
<bean id="myAnnotationListener" class="com.xj.demo3.MyAnnotationListener"/>
</beans>
3.运行结果:
拦截器的执行顺序:
(1)MyJobExecutionListener的before()方法;
(2)MyAnnotationListener的before()方法;
(3)MyAnnotationListener的after()方法;
(4)MyJobExecutionListener的after()方法。