概述
Quartz的监听器用于当任务调度中你所关注事件发生时,能够及时获取这一事件的通知。Quartz监听器主要有JobListener、TriggerListener、SchedulerListener三种,顾名思义,分别表示任务、触发器、调度器对应的监听器。三者的使用方法类似,在开始介绍三种监听器之前,需要明确两个概念:全局监听器与非全局监听器,二者的区别在于:全局监听器能够接收到所有的Job/Trigger的事件通知,而非全局监听器只能接收到在其上注册的Job或Trigger的事件,不在其上注册的Job或Trigger则不会进行监听。
JobListener
任务调度过程中,与任务Job相关的事件包括:job开始要执行的提示; job执行完成的提示灯。其接口如下:
public interface JobListener {
public String getName();
public void jobToBeExecuted(JobExecutionContext context);
public void jobExecutionVetoed(JobExecutionContext context);
public void jobWasExecuted(JobExecutionContext context,
JobExecutionException jobException);
}
-
getName方法:用于获取该JobListener的名称。
-
jobToBeExecuted方法:Scheduler在JobDetail将要被执行时调用这个方法。
-
jobExecutionVetoed方法:Scheduler在JobDetail即将被执行,但又被TriggerListerner否决时会调用该方法
-
jobWasExecuted方法:Scheduler在JobDetail被执行之后调用这个方法
参考如下代码
package com;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
/**
* @program: hello
* @description:
* @author: lee
* @create: 2019-01-17
**/
public class JobListenerDemo implements JobListener {
@Override
public String getName() {
String name=getClass().getSimpleName();
return name;
}
@Override
public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {
String jobname=jobExecutionContext.getJobDetail().getKey().getName();
System.out.println(jobname+"is going to be executed");
}
@Override
public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {
String jobname=jobExecutionContext.getJobDetail().getKey().getName();
System.out.println(jobname+"was vetoed and not executed");
}
@Override
public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {
String jobname=jobExecutionContext.getJobDetail().getKey().getName();
System.out.println(jobname+"was executed");
}
}
package com;
import com.sun.org.apache.xpath.internal.SourceTree;
import org.quartz.*;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @program: hello
* @description: 自定义Job
* @author: lee
* @create: 2019-01-13
**/
public class PJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
Date date=new Date();
SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString=dateFormat.format(date);
System.out.println("正在运行job任务,运行时间是:"+dateString);
}
}
package com;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.EverythingMatcher;
import org.quartz.impl.matchers.KeyMatcher;
import java.util.Date;
/**
* @program: hello
* @description: 任务调度入口
* @author: lee
* @create: 2019-01-13
**/
public class PScheduller {
public static void main(String[] args) throws SchedulerException {
PScheduller exam = new PScheduller();
Scheduler scheduler = exam.createScheduler();
JobDetail jobDetail = exam.createJobDetail("jobid", "jobgroup");
Trigger trigger = exam.createTrigger("tiggername", "triggergroup");
JobDetail jobDetail2 = exam.createJobDetail("jobid2", "jobgroup2");
Trigger trigger2 = exam.createTrigger("tiggername2", "triggergroup2");
scheduler.scheduleJob(jobDetail, trigger);
scheduler.scheduleJob(jobDetail2, trigger2);
// 创建并注册一个全局的Job Listener
//scheduler.getListenerManager().addJobListener(new JobListenerDemo(), EverythingMatcher.allJobs());
// 创建并注册一个指定任务的Job Listener
scheduler.getListenerManager().addJobListener(new JobListenerDemo(), KeyMatcher.keyEquals(JobKey.jobKey("jobid","jobgroup")));
scheduler.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
scheduler.shutdown();
}
protected Scheduler createScheduler() throws SchedulerException {
return StdSchedulerFactory.getDefaultScheduler();
}
protected Trigger createTrigger(String triggerName, String triggerGroup) {
return TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroup)
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(4).repeatForever())
.build();
}
protected JobDetail createJobDetail(String jobName, String jobGroup) {
return JobBuilder.newJob(PJob.class)
.withIdentity(jobName, jobGroup)
.build();
}
}
输出结果 第一种情况
jobidis going to be executed
jobid2is going to be executed
正在运行job任务,运行时间是:2019-01-21 20:29:31
正在运行job任务,运行时间是:2019-01-21 20:29:31
jobidwas executed
jobid2was executed
第二种情况
jobidis going to be executed
正在运行job任务,运行时间是:2019-01-21 20:28:31
jobidwas executed
正在运行job任务,运行时间是:2019-01-21 20:28:31
将同一任务组的任务注册到监听器中
scheduler.getListenerManager().addJobListener(new JobListenerDemo(), GroupMatcher.jobGroupEquals("jobgroup2"));
将两个任务组的任务注册到监听器中
scheduler.getListenerManager().addJobListener(new JobListenerDemo(), OrMatcher.or(GroupMatcher.jobGroupEquals("jobgroup"),
GroupMatcher.jobGroupEquals("jobgroup2")));
TriggerListener
任务调度过程中,与触发器Trigger相关的事件包括:触发器触发、触发器未正常触发、触发器完成等。TriggerListener的接口如下:
public interface TriggerListener {
public String getName();
public void triggerFired(Trigger trigger, JobExecutionContext context);
public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context);
public void triggerMisfired(Trigger trigger);
public void triggerComplete(Trigger trigger, JobExecutionContext context,
int triggerInstructionCode);
}
-
getName方法:用于获取触发器的名称
-
triggerFired方法:当与监听器相关联的Trigger被触发,Job上的execute()方法将被执行时,Scheduler就调用该方法。
-
vetoJobExecution方法:在 Trigger 触发后,Job 将要被执行时由 Scheduler 调用这个方法。TriggerListener 给了一个选择去否决 Job 的执行。假如这个方法返回 true,这个 Job 将不会为此次 Trigger 触发而得到执行。
-
triggerMisfired方法:Scheduler 调用这个方法是在 Trigger 错过触发时。你应该关注此方法中持续时间长的逻辑:在出现许多错过触发的 Trigger 时,长逻辑会导致骨牌效应。你应当保持这上方法尽量的小。
-
triggerComplete方法:Trigger 被触发并且完成了 Job 的执行时,Scheduler 调用这个方法。
代码如下
package com;
import org.quartz.JobExecutionContext;
import org.quartz.Trigger;
import org.quartz.TriggerListener;
/**
* @program: hello
* @description:
* @author: lee
* @create: 2019-01-21
**/
public class TriggerListenerDemo implements TriggerListener {
private String name;
public TriggerListenerDemo(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public void triggerFired(Trigger trigger, JobExecutionContext jobExecutionContext) {
String name=trigger.getKey().getName();
System.out.println("trigger name is "+name);
}
@Override
public boolean vetoJobExecution(Trigger trigger, JobExecutionContext jobExecutionContext) {
return false;
}
@Override
public void triggerMisfired(Trigger trigger) {
String name=trigger.getKey().getName();
System.out.println("triggerMisfired is running "+name);
}
@Override
public void triggerComplete(Trigger trigger, JobExecutionContext jobExecutionContext, Trigger.CompletedExecutionInstruction completedExecutionInstruction) {
String name=trigger.getKey().getName();
System.out.println("triggerComplete is running "+name);
}
}
调度程序中需要加入
scheduler.getListenerManager().addTriggerListener(new TriggerListenerDemo("TriggerListenerDemo"),
GroupMatcher.groupEquals("triggergroup"));
SchedulerListener
SchedulerListener会在Scheduler的生命周期中关键事件发生时被调用。与Scheduler有关的事件包括:增加一个job/trigger,删除一个job/trigger,scheduler发生严重错误,关闭scheduler等。
public interface SchedulerListener {
public void jobScheduled(Trigger trigger);
public void jobUnscheduled(String triggerName, String triggerGroup);
public void triggerFinalized(Trigger trigger);
public void triggersPaused(String triggerName, String triggerGroup);
public void triggersResumed(String triggerName, String triggerGroup);
public void jobsPaused(String jobName, String jobGroup);
public void jobsResumed(String jobName, String jobGroup);
public void schedulerError(String msg, SchedulerException cause);
public void schedulerStarted();
public void schedulerInStandbyMode();
public void schedulerShutdown();
public void schedulingDataCleared();
}
-
jobScheduled方法:用于部署JobDetail时调用
-
jobUnscheduled方法:用于卸载JobDetail时调用
-
triggerFinalized方法:当一个 Trigger 来到了再也不会触发的状态时调用这个方法。除非这个 Job 已设置成了持久性,否则它就会从 Scheduler 中移除。
-
triggersPaused方法:Scheduler 调用这个方法是发生在一个 Trigger 或 Trigger 组被暂停时。假如是 Trigger 组的话,triggerName 参数将为 null。
-
triggersResumed方法:Scheduler 调用这个方法是发生成一个 Trigger 或 Trigger 组从暂停中恢复时。假如是 Trigger 组的话,假如是 Trigger 组的话,triggerName 参数将为 null。参数将为 null。
-
jobsPaused方法:当一个或一组 JobDetail 暂停时调用这个方法。
-
jobsResumed方法:当一个或一组 Job 从暂停上恢复时调用这个方法。假如是一个 Job 组,jobName 参数将为 null。
-
schedulerError方法:在 Scheduler 的正常运行期间产生一个严重错误时调用这个方法。
-
schedulerStarted方法:当Scheduler 开启时,调用该方法
-
schedulerInStandbyMode方法: 当Scheduler处于StandBy模式时,调用该方法
-
schedulerShutdown方法:当Scheduler停止时,调用该方法
-
schedulingDataCleared方法:当Scheduler中的数据被清除时,调用该方法。
示例:
package com;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @program: hello
* @description:
* @author: lee
* @create: 2019-01-21
**/
public class SchedullerListener implements SchedulerListener {
private static Logger logger = LoggerFactory.getLogger(SchedullerListener.class);
@Override
public void jobScheduled(Trigger trigger) {
String jobName = trigger.getJobKey().getName();
System.out.println(jobName + " has been scheduled");
}
@Override
public void jobUnscheduled(TriggerKey triggerKey) {
System.out.println(triggerKey + " is being unscheduled");
}
@Override
public void triggerFinalized(Trigger trigger) {
System.out.println("Trigger is finished for " + trigger.getJobKey().getName());
}
@Override
public void triggerPaused(TriggerKey triggerKey) {
System.out.println(triggerKey + " is being paused");
}
@Override
public void triggersPaused(String triggerGroup) {
System.out.println("trigger group "+triggerGroup + " is being paused");
}
@Override
public void triggerResumed(TriggerKey triggerKey) {
System.out.println(triggerKey + " is being resumed");
}
@Override
public void triggersResumed(String triggerGroup) {
System.out.println("trigger group "+triggerGroup + " is being resumed");
}
@Override
public void jobAdded(JobDetail jobDetail) {
System.out.println(jobDetail.getKey()+" is added");
}
@Override
public void jobDeleted(JobKey jobKey) {
System.out.println(jobKey+" is deleted");
}
@Override
public void jobPaused(JobKey jobKey) {
System.out.println(jobKey+" is paused");
}
@Override
public void jobsPaused(String jobGroup) {
System.out.println("job group "+jobGroup+" is paused");
}
@Override
public void jobResumed(JobKey jobKey) {
System.out.println(jobKey+" is resumed");
}
@Override
public void jobsResumed(String jobGroup) {
System.out.println("job group "+jobGroup+" is resumed");
}
@Override
public void schedulerError(String msg, SchedulerException cause) {
System.out.println(cause.getUnderlyingException());
}
@Override
public void schedulerInStandbyMode() {
logger.info("scheduler is in standby mode");
}
@Override
public void schedulerStarted() {
logger.info("scheduler has been started");
}
@Override
public void schedulerStarting() {
logger.info("scheduler is being started");
}
@Override
public void schedulerShutdown() {
logger.info("scheduler has been shutdown");
}
@Override
public void schedulerShuttingdown() {
logger.info("scheduler is being shutdown");
}
@Override
public void schedulingDataCleared() {
logger.info("scheduler has cleared all data");
}
}
调度器代码
package com;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.EverythingMatcher;
import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.impl.matchers.KeyMatcher;
import org.quartz.impl.matchers.OrMatcher;
import java.util.Date;
/**
* @program: hello
* @description: 任务调度入口
* @author: lee
* @create: 2019-01-13
**/
public class PScheduller {
public static void main(String[] args) throws SchedulerException, InterruptedException {
PScheduller exam = new PScheduller();
Scheduler scheduler = exam.createScheduler();
JobDetail jobDetail = exam.createJobDetail("jobid", "jobgroup");
Trigger trigger = exam.createTrigger("tiggername", "triggergroup");
scheduler.scheduleJob(jobDetail, trigger);
// 创建SchedulerListener
scheduler.getListenerManager().addSchedulerListener(new SchedullerListener());
scheduler.start();
Thread.sleep(20000);
scheduler.shutdown();
}
protected Scheduler createScheduler() throws SchedulerException {
return StdSchedulerFactory.getDefaultScheduler();
}
protected Trigger createTrigger(String triggerName, String triggerGroup) {
return TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroup)
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(4).repeatForever())
.build();
}
protected JobDetail createJobDetail(String jobName, String jobGroup) {
return JobBuilder.newJob(PJob.class)
.withIdentity(jobName, jobGroup)
.build();
}
}
来源:oschina
链接:https://my.oschina.net/u/3798913/blog/3004233