我们有这么一种需求,在每个任务运行结束之后发送通知给运维管理员。那是不是要在每个任务的最后添加一行代码呢?这种方式对原来的代码造成了入侵,不利于维护。如果代码不是写在任务代码的最后一行,怎么知道任务执行完了呢?或者说,怎么监测到任务的生命周期呢?
观察者模式:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖它的对象都会得到通知并自动更新。
Quartz中提供了三种 Listener,监听 Scheduler的,监听 Trigger的,监听 Job的。
只需要创建类实现相应的接口,并在 Scheduler上注册 Listener,便可实现对核心对象的监听。
public class MyJobListenerTest {
public static void main(String[] args) throws SchedulerException {
// JobDetail
JobDetail jobDetail = JobBuilder.newJob(MyJob1.class).withIdentity("job1", "group1").build();
// Trigger
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).repeatForever()).build();
// SchedulerFactory
SchedulerFactory factory = new StdSchedulerFactory();
// Scheduler
Scheduler scheduler = factory.getScheduler();
scheduler.scheduleJob(jobDetail, trigger);
// 创建并注册一个全局的Job Listener
scheduler.getListenerManager().addJobListener(new MyJobListener(), EverythingMatcher.allJobs());
scheduler.start();
}
}
public class MySchedulerListenerTest {
public static void main(String[] args) throws SchedulerException {
// JobDetail
JobDetail jobDetail = JobBuilder.newJob(MyJob1.class).withIdentity("job1", "group1").build();
// Trigger
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).repeatForever()).build();
// SchedulerFactory
SchedulerFactory factory = new StdSchedulerFactory();
// Scheduler
Scheduler scheduler = factory.getScheduler();
scheduler.scheduleJob(jobDetail, trigger);
// 创建Scheduler Listener
scheduler.getListenerManager().addSchedulerListener(new MySchedulerListener());
scheduler.start();
}
}
public class MyTriggerListenerTest {
public static void main(String[] args) throws SchedulerException {
// JobDetail
JobDetail jobDetail = JobBuilder.newJob(MyJob1.class).withIdentity("job1", "group1").build();
// Trigger
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(10).repeatForever()).build();
// SchedulerFactory
SchedulerFactory factory = new StdSchedulerFactory();
// Scheduler
Scheduler scheduler = factory.getScheduler();
scheduler.scheduleJob(jobDetail, trigger);
// 创建并注册一个全局的Trigger Listener
scheduler.getListenerManager().addTriggerListener(new MyTriggerListener("myListener1"), EverythingMatcher.allTriggers());
// 创建并注册一个局部的Trigger Listener
scheduler.getListenerManager().addTriggerListener(new MyTriggerListener("myListener2"), KeyMatcher.keyEquals(TriggerKey.triggerKey("trigger1", "gourp1")));
// 创建并注册一个特定组的Trigger Listener
GroupMatcher<TriggerKey> matcher = GroupMatcher.triggerGroupEquals("gourp1");
scheduler.getListenerManager().addTriggerListener(new MyTriggerListener("myListener3"), matcher);
scheduler.start();
}
}
JobListener
四个方法:
方法 | 作用或执行实际 |
---|---|
getName() | 返回JobListener 的名称 |
jobToBeExecuted() | Scheduler 在JobDetail 将要被执行时调用这个方法 |
jobExecutionVetoed() | Scheduler 在JobDetail 即将被执行,但又被TriggerListener 否决了时调用这个 方法 |
jobWasExecuted() | Scheduler 在JobDetail 被执行之后调用这个方法 |
工具类:ListenerManager,用于添加、获取、移除监听器
工具类:Matcher,主要是基于 groupName和 keyName进行匹配。
TriggerListener
方法 | 作用或执行实际 |
---|---|
getName() | 返回监听器的名称 |
triggerFired() | Trigger 被触发,Job 上的execute() 方法将要被执行时,Scheduler 就调用这个 方法 |
vetoJobExecution() | 在Trigger 触发后, Job 将要被执行时由Scheduler 调用这个方法。 TriggerListener 给了一个选择去否决Job 的执行。假如这个方法返回true,这 个Job 将不会为此次Trigger 触发而得到执行 |
triggerMisfired() | Trigger 错过触发时调用 |
triggerComplete() | Trigger 被触发并且完成了Job 的执行时,Scheduler 调用这个方法 |