JobListener 可用于监听定时任务执行的事件, 并在定时任务执行前后做一些自定义操作, 类似于java 切面编程的环绕通知. 需要注意的时,quartz 2.x系列, 监听器已不再进行持久化操作, 自然也就没有分布式监听这一说了. 在quartz 1.x 时, 数据库表还有监听器相关的表, 笔者猜测quartz1.x 应该对监听器也做了持久化吧. 在自定义
1. JobListener 定义
quartz 提供了两种方式自定义自己的JobListner, 一种是实现JobListener接口, 需要实现所有Listener 自定义的方法; 另一种是继承JobListenerSuppoer 类, 只需实现自己关注的方法即可.
1.1 JobListener 接口定义
public interface JobListener {
// 监听器名称
public String getName();
// 定时任务执行前执行, 相当于切面编程中的前置通知
public void jobToBeExecuted(JobExecutionContext context);
// TriggerListener 否决了执行时触发
public void jobExecutionVetoed(JobExecutionContext context);
// 定时任务执行后执行, 相当于切面编程中的后置通知
public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException);
}
1.2 监听器匹配模式
quartz 提供了Matcher 接口用于指定监听器匹配任务的模式, 可具体匹配的定时任务, 或按组进行屁, 亦或者匹配全部的定时任务
// 监听具体的一个定时任务
KeyMatcher<JobKey> jobKeyMatcher = KeyMatcher.keyEquals(JobKey.jobKey("jobName1", "jobGroupName1"));
// 监听一组定时任务
GroupMatcher<JobKey> jobGroupMatcher = GroupMatcher.groupEquals("jobGroupName");
// 监听所有的任务分组
GroupMatcher<JobKey> allMatcher = GroupMatcher.anyJobGroup();
1.3 注册JobListener
# 1. 创建监听器匹配模式
KeyMatcher<JobKey> jobKeyMatcher = KeyMatcher.keyEquals(JobKey.jobKey("listenerJob", "jobGroup7"));
# 2. 注册监听器
scheduler.getListenerManager().addJobListener(new MyFirstJobListener(), jobKeyMatcher);
2. 自定义JobListener
由于quartz 2.x 并不会对监听器做持久化操作, 因此笔者使用基于ram 配置的quartz环境.
2.1 实现JobListener接口
必须实现JobListener接口的所有方法,
public class MyFirstJobListener implements JobListener {
@Override
public String getName() {
return "firstJobListener";
}
@Override
public void jobToBeExecuted(JobExecutionContext context) {
System.out.println(getName() + "-jobToBeExecuted....");
}
@Override
public void jobExecutionVetoed(JobExecutionContext context) {
System.out.println(getName() + "-jobExecutionVetoed....");
}
@Override
public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
System.out.println(getName() + "-jobWasExecuted....");
}
}
2.2 继承JobListenerSupport
其实和实现jobListener接口无差异, getName()是必须重写的方法.
public class MySecondJobListener extends JobListenerSupport {
@Override
public String getName() {
return "secondJobListener";
}
@Override
public void jobToBeExecuted(JobExecutionContext context) {
System.out.println(getName() + "-jobToBeExecuted....");
}
@Override
public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
System.out.println(getName() + "-jobWasExecuted....");
}
}
2.3 测试用例
笔者推荐在调度器启动之前添加任务监听器.
public class Test07 extends BaseQuartzJdbcTest{
// 测试job监听器
@Test
public void test_jobListener() throws SchedulerException {
// 添加scheduler 监听器
scheduler.getListenerManager().addSchedulerListener(new MyScheduerListener());
// 3. 创建定时任务
JobDetail job = JobBuilder.newJob(ListenerJob.class)
.withIdentity("listenerJob", "jobGroup7")
.requestRecovery(true)
.build();
// 4. 创建简单触发器
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("jobListenerTrigger", "triggerGroup7")
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withRepeatCount(0))
.build();
// 5. 将定时任务添加到调度队列中
scheduler.scheduleJob(job, trigger);
// 6. 笔者推荐在调度器启动之前添加监听器
// 自定义监听器匹配模式
KeyMatcher<JobKey> jobKeyMatcher = KeyMatcher.keyEquals(JobKey.jobKey("listenerJob", "jobGroup7"));
// 依次添加监听器1和监听器2
scheduler.getListenerManager().addJobListener(new MyFirstJobListener(), jobKeyMatcher);
scheduler.getListenerManager().addJobListener(new MySecondJobListener(), jobKeyMatcher);
// 7. 启动调度器
scheduler.start();
}
// 重新启动之后, 并无监听. 说明quartz并不会持久化监听器
@Test
public void start() throws SchedulerException {
this.scheduler.start();
}
}
2.4 测试输出
从输出结果来看, 可以发现执行步骤:
- 执行监听器1 的jobToBeExecuted方法
- 执行监听器2 的jobToBeExecuted方法
- 执行定时任务的方法
- 执行监听器2的jobWasExecuted的方法
- 执行监听器1的jobWasExecuted的方法
firstJobListener-jobToBeExecuted....
secondJobListener-jobToBeExecuted....
org.zongf.learn.quartz.l01.job.ListenerJob- do job...
firstJobListener-jobWasExecuted....
secondJobListener-jobWasExecuted....
来源:https://blog.csdn.net/zongf0504/article/details/89241461