1. 概述

Quartz的监听器用于当任务调度中你所关注事件发生时,能够及时获取这一事件的通知。类似于任务执行过程中的邮件、短信类的提醒。Quartz监听器主要有JobListener、TriggerListener、SchedulerListener三种,顾名思义,分别表示任务、触发器、调度器对应的监听器。三者的使用方法类似,在开始介绍三种监听器之前,需要明确两个概念:全局监听器与非全局监听器,二者的区别在于:全局监听器能够接收到所有的Job/Trigger的事件通知,而非全局监听器只能接收到在其上注册的Job或Trigger的事件,不在其上注册的Job或Trigger则不会进行监听。关于全局与非全局的监听器的使用,在本文中会做一介绍。

2. 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); }

其中:

1) getName方法:用于获取该JobListener的名称。

2) jobToBeExecuted方法:Scheduler在JobDetail将要被执行时调用这个方法。

3) jobExecutionVetoed方法:Scheduler在JobDetail即将被执行,但又被TriggerListerner否决时会调用该方法

4) jobWasExecuted方法:Scheduler在JobDetail被执行之后调用这个方法

示例:

下面的代码展示了简单使用JobListener的使用,其中区别了全局监听器与非全局监听器的创建及使用方法。

1) 简单的HelloWordJob创建

package org.ws.quartz.test3;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class HelloWorldJob implements Job{ private static Logger logger = LoggerFactory.getLogger(HelloWorldJob.class); @Override
public void execute(JobExecutionContext context) throws JobExecutionException {
logger.info("Hello World");
}
}

2) 创建简单的JobListener

package org.ws.quartz.test3;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class SimpleJobListener implements JobListener{ private static Logger logger = LoggerFactory.getLogger(SimpleJobListener.class); @Override
public String getName() {
String name = getClass().getSimpleName();
logger.info(" listener name is:"+name);
return name;
} @Override
public void jobToBeExecuted(JobExecutionContext context) {
String jobName = context.getJobDetail().getKey().getName();
logger.info(jobName + " is going to be executed");
} @Override
public void jobExecutionVetoed(JobExecutionContext context) {
String jobName = context.getJobDetail().getKey().getName();
logger.info(jobName + " was vetoed and not executed");
} @Override
public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
String jobName = context.getJobDetail().getKey().getName();
logger.info(jobName + " was executed"); }
}

3) 调度器的创建与执行

package org.ws.quartz.test3;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.EverythingMatcher;
import org.quartz.impl.matchers.KeyMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class SimpleQuartzExample { private static Logger logger = LoggerFactory.getLogger(SimpleQuartzExample.class); public static void main(String[] args) throws SchedulerException, InterruptedException { SimpleQuartzExample exam = new SimpleQuartzExample(); logger.info("init scheduler componets"); // 创建调度器
Scheduler scheduler = exam.createScheduler(); // 创建两个任务及对应的触发器
JobDetail jobDetail1 = exam.createJobDetail("HelloWord1_Job", "HelloWorld1_Group");
Trigger trigger1 = exam.createTrigger("HelloWord1_Job", "HelloWorld1_Group"); JobDetail jobDetail2 = exam.createJobDetail("HelloWord2_Job", "HelloWorld2_Group");
Trigger trigger2 = exam.createTrigger("HelloWord2_Job", "HelloWorld2_Group"); // 构建调度任务
scheduler.scheduleJob(jobDetail1, trigger1);
scheduler.scheduleJob(jobDetail2, trigger2); // 创建并注册一个全局的Job Listener
scheduler.getListenerManager().addJobListener(new SimpleJobListener(), EverythingMatcher.allJobs()); // 创建并注册一个指定任务的Job Listener
// scheduler.getListenerManager().addJobListener(new SimpleJobListener(), KeyMatcher.keyEquals(JobKey.jobKey("HelloWorld1_Job", "HelloWorld1_Group"))); logger.info("execute scheduler");
// 开启调度器
scheduler.start(); Thread.sleep(20000); scheduler.shutdown(); logger.info("shut down scheduler");
} protected Scheduler createScheduler() throws SchedulerException{
return StdSchedulerFactory.getDefaultScheduler();
} protected JobDetail createJobDetail(String jobName, String jobGroup){
return JobBuilder.newJob(HelloWorldJob.class)
.withIdentity(jobName, jobGroup)
.build();
} protected Trigger createTrigger(String triggerName, String triggerGroup){
return TriggerBuilder.newTrigger()
.withIdentity(triggerName, triggerGroup)
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(10)
.repeatForever()
).build();
}
}

① 执行全局监听器的结果如下:

2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] init scheduler componets
2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] execute scheduler
2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job is going to be executed
2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.HelloWorldJob1] Hello World
2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job was executed
2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord2_Job is going to be executed
2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.HelloWorldJob1] Hello World
2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord2_Job was executed
2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job is going to be executed
2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.HelloWorldJob1] Hello World
2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job was executed
2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord2_Job is going to be executed
2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.HelloWorldJob1] Hello World
2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord2_Job was executed

② 将代码中的注释去掉,并注释全区监听器的创建,执行非全局监听器结果如下:

2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] init scheduler componets
2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] execute scheduler
2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job is going to be executed
2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job was executed
2017-07-16 17:33:07 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:33:07 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job is going to be executed
2017-07-16 17:33:07 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
2017-07-16 17:33:07 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:33:07 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job was executed
2017-07-16 17:33:07 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:33:07 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
2017-07-16 17:33:07 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job is going to be executed
2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job was executed
2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.SimpleJobListener] listener name is:SimpleJobListener
2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] shut down scheduler

备注:

除了代码中将对应的job注册到监听器中的两种方法,也有如下几种其他方法:

1) 将同一任务组的任务注册到监听器中

scheduler.getListenerManager().addJobListener(new SimpleJobListener(), GroupMatcher.jobGroupEquals("HelloWorld2_Group"));

2) 将两个任务组的任务注册到监听器中

scheduler.getListenerManager().addJobListener(new SimpleJobListener(), OrMatcher.or(GroupMatcher.jobGroupEquals("HelloWorld1_Group"), GroupMatcher.jobGroupEquals("HelloWorld2_Group")));

3. 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);
}

其中:

1) getName方法:用于获取触发器的名称

2) triggerFired方法:当与监听器相关联的Trigger被触发,Job上的execute()方法将被执行时,Scheduler就调用该方法。

3) vetoJobExecution方法:在 Trigger 触发后,Job 将要被执行时由 Scheduler 调用这个方法。TriggerListener 给了一个选择去否决 Job 的执行。假如这个方法返回 true,这个 Job 将不会为此次 Trigger 触发而得到执行。

4) triggerMisfired方法:Scheduler 调用这个方法是在 Trigger 错过触发时。你应该关注此方法中持续时间长的逻辑:在出现许多错过触发的 Trigger 时,长逻辑会导致骨牌效应。你应当保持这上方法尽量的小。

5) triggerComplete方法:Trigger 被触发并且完成了 Job 的执行时,Scheduler 调用这个方法。

示例:

下面的例子简单展示了TriggerListener的使用,其中创建并注册TriggerListener与JobListener几乎类似。

1) HelloWorldJob类

package org.ws.quartz.test3;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class HelloWorldJob implements Job{ private static Logger logger = LoggerFactory.getLogger(HelloWorldJob.class); @Override
public void execute(JobExecutionContext context) throws JobExecutionException {
logger.info("Hello World");
}
}

2) SimpleTriggerListener

package org.ws.quartz.test3;

import org.quartz.JobExecutionContext;
import org.quartz.Trigger;
import org.quartz.Trigger.CompletedExecutionInstruction;
import org.quartz.TriggerListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class SimpleTriggerListener implements TriggerListener{ private static Logger logger = LoggerFactory.getLogger(SimpleTriggerListener.class); private String name; public SimpleTriggerListener(String name) {
this.name = name;
} @Override
public String getName() {
return name;
} @Override
public void triggerFired(Trigger trigger, JobExecutionContext context) {
String triggerName = trigger.getKey().getName();
logger.info(triggerName + " was fired");
} @Override
public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
String triggerName = trigger.getKey().getName();
logger.info(triggerName + " was not vetoed");
return false;
} @Override
public void triggerMisfired(Trigger trigger) {
String triggerName = trigger.getKey().getName();
logger.info(triggerName + " misfired");
} @Override
public void triggerComplete(Trigger trigger, JobExecutionContext context,
CompletedExecutionInstruction triggerInstructionCode) {
String triggerName = trigger.getKey().getName();
logger.info(triggerName + " is complete");
}
}

3) 任务调度与运行,涉及到多种TriggerListener的创建与注册。

package org.ws.quartz.test3;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class SimpleQuartzExample { private static Logger logger = LoggerFactory.getLogger(SimpleQuartzExample.class); public static void main(String[] args) throws SchedulerException, InterruptedException { SimpleQuartzExample exam = new SimpleQuartzExample(); logger.info("init scheduler componets"); // 创建调度器
Scheduler scheduler = exam.createScheduler(); // 创建两个任务及对应的触发器
JobDetail jobDetail1 = exam.createJobDetail("HelloWord1_Job", "HelloWorld1_Group");
Trigger trigger1 = exam.createTrigger("HelloWord1_Job", "HelloWorld1_Group"); JobDetail jobDetail2 = exam.createJobDetail("HelloWord2_Job", "HelloWorld2_Group");
Trigger trigger2 = exam.createTrigger("HelloWord2_Job", "HelloWorld2_Group"); // 构建调度任务
scheduler.scheduleJob(jobDetail1, trigger1);
scheduler.scheduleJob(jobDetail2, trigger2); // 创建并注册一个全局的Trigger Listener
scheduler.getListenerManager().addTriggerListener(new SimpleTriggerListener("SimpleTrigger"), EverythingMatcher.allTriggers()); // 创建并注册一个局部的Trigger Listener
// scheduler.getListenerManager().addTriggerListener(new SimpleTriggerListener("SimpleTrigger"), KeyMatcher.keyEquals(TriggerKey.triggerKey("HelloWord1_Job", "HelloWorld1_Group"))); // 创建并注册一个特定组的Trigger Listener
// scheduler.getListenerManager().addTriggerListener(new SimpleTriggerListener("SimpleTrigger"), GroupMatcher.groupEquals("HelloWorld1_Group")); logger.info("execute scheduler");
// 开启调度器""
scheduler.start(); Thread.sleep(20000); scheduler.shutdown(); logger.info("shut down scheduler");
} protected Scheduler createScheduler() throws SchedulerException{
return StdSchedulerFactory.getDefaultScheduler();
} protected JobDetail createJobDetail(String jobName, String jobGroup){
return JobBuilder.newJob(HelloWorldJob.class)
.withIdentity(jobName, jobGroup)
.build();
} protected Trigger createTrigger(String triggerName, String triggerGroup){
return TriggerBuilder.newTrigger()
.withIdentity(triggerName, triggerGroup)
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(10)
.repeatForever()
).build();
}
}

执行全局监听器的结果如下:

2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] init scheduler componets
2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] execute scheduler
2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job was fired
2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job was not vetoed
2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job is complete
2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job was fired
2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job was not vetoed
2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job is complete
2017-07-16 18:32:08 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job was fired
2017-07-16 18:32:08 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job was not vetoed
2017-07-16 18:32:08 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
2017-07-16 18:32:08 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job is complete
2017-07-16 18:32:08 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job was fired
2017-07-16 18:32:08 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job was not vetoed
2017-07-16 18:32:08 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
2017-07-16 18:32:08 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job is complete
2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job was fired
2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job was not vetoed
2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job is complete
2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job was fired
2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job was not vetoed
2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job is complete
2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] shut down scheduler

4. SchedulerListener

SchedulerListener会在Scheduler的生命周期中关键事件发生时被调用。与Scheduler有关的事件包括:增加一个job/trigger,删除一个job/trigger,scheduler发生严重错误,关闭scheduler等。

SchedulerListener的接口如下:

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();
}

其中:

1) jobScheduled方法:用于部署JobDetail时调用

2) jobUnscheduled方法:用于卸载JobDetail时调用

3) triggerFinalized方法:当一个 Trigger 来到了再也不会触发的状态时调用这个方法。除非这个 Job 已设置成了持久性,否则它就会从 Scheduler 中移除。

4) triggersPaused方法:Scheduler 调用这个方法是发生在一个 Trigger 或 Trigger 组被暂停时。假如是 Trigger 组的话,triggerName 参数将为 null。

5) triggersResumed方法:Scheduler 调用这个方法是发生成一个 Trigger 或 Trigger 组从暂停中恢复时。假如是 Trigger 组的话,假如是 Trigger 组的话,triggerName 参数将为 null。参数将为 null。
6) jobsPaused方法:当一个或一组 JobDetail 暂停时调用这个方法。
7) jobsResumed方法:当一个或一组 Job 从暂停上恢复时调用这个方法。假如是一个 Job 组,jobName 参数将为 null。
8) schedulerError方法:在 Scheduler 的正常运行期间产生一个严重错误时调用这个方法。
9) schedulerStarted方法:当Scheduler 开启时,调用该方法
10) schedulerInStandbyMode方法: 当Scheduler处于StandBy模式时,调用该方法
11) schedulerShutdown方法:当Scheduler停止时,调用该方法
12) schedulingDataCleared方法:当Scheduler中的数据被清除时,调用该方法。

示例:

下面的代码简单描述了如何使用SchedulerListener方法:

1) HelloWorldJob

package org.ws.quartz.test3;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class HelloWorldJob implements Job{ private static Logger logger = LoggerFactory.getLogger(HelloWorldJob.class); @Override
public void execute(JobExecutionContext context) throws JobExecutionException {
logger.info("Hello World");
}
}

2) 简单的SchedulerListener

package org.ws.quartz.test3;

import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.SchedulerException;
import org.quartz.SchedulerListener;
import org.quartz.Trigger;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class SimpleSchedulerListener implements SchedulerListener{ private static Logger logger = LoggerFactory.getLogger(SimpleSchedulerListener.class); @Override
public void jobScheduled(Trigger trigger) {
String jobName = trigger.getJobKey().getName();
logger.info(jobName + " has been scheduled");
} @Override
public void jobUnscheduled(TriggerKey triggerKey) {
logger.info(triggerKey + " is being unscheduled");
} @Override
public void triggerFinalized(Trigger trigger) {
logger.info("Trigger is finished for " + trigger.getJobKey().getName());
} @Override
public void triggerPaused(TriggerKey triggerKey) {
logger.info(triggerKey + " is being paused");
} @Override
public void triggersPaused(String triggerGroup) {
logger.info("trigger group "+triggerGroup + " is being paused");
} @Override
public void triggerResumed(TriggerKey triggerKey) {
logger.info(triggerKey + " is being resumed");
} @Override
public void triggersResumed(String triggerGroup) {
logger.info("trigger group "+triggerGroup + " is being resumed");
} @Override
public void jobAdded(JobDetail jobDetail) {
logger.info(jobDetail.getKey()+" is added");
} @Override
public void jobDeleted(JobKey jobKey) {
logger.info(jobKey+" is deleted");
} @Override
public void jobPaused(JobKey jobKey) {
logger.info(jobKey+" is paused");
} @Override
public void jobsPaused(String jobGroup) {
logger.info("job group "+jobGroup+" is paused");
} @Override
public void jobResumed(JobKey jobKey) {
logger.info(jobKey+" is resumed");
} @Override
public void jobsResumed(String jobGroup) {
logger.info("job group "+jobGroup+" is resumed");
} @Override
public void schedulerError(String msg, SchedulerException cause) {
logger.error(msg, 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");
}
}

3) 任务调度以及SchedulerListener的加载调用

package org.ws.quartz.test3;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class SimpleQuartzExample { private static Logger logger = LoggerFactory.getLogger(SimpleQuartzExample.class); public static void main(String[] args) throws SchedulerException, InterruptedException { SimpleQuartzExample exam = new SimpleQuartzExample(); logger.info("init scheduler componets"); // 创建调度器
Scheduler scheduler = exam.createScheduler(); // 创建任务及对应的触发器
JobDetail jobDetail = exam.createJobDetail("HelloWord_Job", "HelloWorld_Group");
Trigger trigger = exam.createTrigger("HelloWord_Job", "HelloWorld_Group"); // 构建调度任务
scheduler.scheduleJob(jobDetail, trigger); // 创建SchedulerListener
scheduler.getListenerManager().addSchedulerListener(new SimpleSchedulerListener()); // 移除对应的SchedulerListener
// scheduler.getListenerManager().removeSchedulerListener(new SimpleSchedulerListener()); logger.info("execute scheduler");
// 开启调度器""
scheduler.start(); Thread.sleep(20000); scheduler.shutdown(); logger.info("shut down scheduler");
} protected Scheduler createScheduler() throws SchedulerException{
return StdSchedulerFactory.getDefaultScheduler();
} protected JobDetail createJobDetail(String jobName, String jobGroup){
return JobBuilder.newJob(HelloWorldJob.class)
.withIdentity(jobName, jobGroup)
.build();
} protected Trigger createTrigger(String triggerName, String triggerGroup){
return TriggerBuilder.newTrigger()
.withIdentity(triggerName, triggerGroup)
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(10)
.repeatForever()
).build();
}
}

执行后的结果如下:

2017-07-16 19:13:59 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] init scheduler componets
2017-07-16 19:14:00 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] execute scheduler
2017-07-16 19:14:00 [INFO]-[org.ws.quartz.test3.SimpleSchedulerListener] scheduler is being started
2017-07-16 19:14:00 [INFO]-[org.ws.quartz.test3.SimpleSchedulerListener] scheduler has been started
2017-07-16 19:14:00 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
2017-07-16 19:14:10 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
2017-07-16 19:14:20 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
2017-07-16 19:14:20 [INFO]-[org.ws.quartz.test3.SimpleSchedulerListener] scheduler is in standby mode
2017-07-16 19:14:20 [INFO]-[org.ws.quartz.test3.SimpleSchedulerListener] scheduler is being shutdown
2017-07-16 19:14:20 [INFO]-[org.ws.quartz.test3.SimpleSchedulerListener] scheduler has been shutdown
2017-07-16 19:14:20 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] shut down scheduler

Quartz使用(4) - Quartz监听器Listerner的更多相关文章

  1. 定时组件quartz系列<二>quartz的集群原理

    1.基本信息:      Quartz是一个开源的作业调度框架,它完全由java写成,并设计用于J2Se和J2EE应用中.它提供了巨大的灵活性而不牺牲简单性.你能够用它 来为执行一个作业而创建简单的或 ...

  2. 实现quartz定时器及quartz定时器原理介绍(转)

    一.核心概念 Quartz的原理不是很复杂,只要搞明白几个概念,然后知道如何去启动和关闭一个调度程序即可.1.Job表示一个工作,要执行的具体内容.此接口中只有一个方法void execute(Job ...

  3. 实现quartz定时器及quartz定时器原理介绍

    今天研究定时器,在网上看了一篇不错的文章,推荐给大家! 实现quartz定时器及quartz定时器原理介绍

  4. 【Quartz.NET】Quartz.NET 入门

    概述 Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等. Quartz.NET允许开发人员根据时间间隔(或天)来调度作业.它实现了 ...

  5. Net作业调度(一) -Quartz.Net入门 Quartz表达式生成器 [转]

    背景 很多时候,项目需要在不同个时刻,执行一个或很多个不同的作业. Windows执行计划这时并不能很好的满足需求了. 这时候需要一个更为强大,方便管理,集部署的作业调度了. 介绍 Quartz一个开 ...

  6. quartz (一) 基于 Quartz 开发企业级任务调度应用

    本文转自:http://www.ibm.com/developerworks/cn/opensource/os-cn-quartz/ Quartz 基本概念及原理 Quartz Scheduler 开 ...

  7. Quartz简介 用 Quartz 进行作业调度

    http://www.ibm.com/developerworks/cn/java/j-quartz/现代的 Web 应用程序框架在范围和复杂性方面都有所发展,应用程序的每个底层组件也必须相应地发展. ...

  8. Quartz使用(6) - Quartz项目实战

    本片博文将阐述项目工作中使用Quartz的情况,包含项目背景.项目框架.Quartz集群部署等方面,重点讲述如何在实际项目中使用Quartz. 1. 背景 因项目需求,需要定时调用数据下载接口,并将数 ...

  9. Quartz使用(5) - Quartz的Job存储及集群部署

    1. Job的存储与持久化 Quartz的JobStore接口定义了作业Job.触发器trigger.调度器Scheduler等数据存储机制.Quartz主要有两种Job存储类型:内存存储RAMJob ...

随机推荐

  1. 读取txt文件的简易算法

    网友在问,从一个文本文件(txt)读取数据,并做简易算法.网友的原问题大约如下, 网友的问题,虽然说是全部是数字,但没有说明是否只有一行.因此Insus.NET在实现算法时,处理文本文件是否多行,是否 ...

  2. 写一个Android输入法02——候选窗、转换

    上一篇介绍了完成Android输入法的最小化步骤,它只能将按键对应的字符上屏.一般的东亚语言都有一个转换的过程,比如汉语输入拼音,需要由拼音转成汉字再上屏.本文将在前文基础上加入完成转换过程所必需的候 ...

  3. ubuntu - 14.04,由于安装软件造成磁盘空间不足,无法登入Gnome解决办法!!

    刚才安装了半天软件,最后出现磁盘空间不足的问题,刚开始我还以为ubuntu和我开玩笑,随后我重新启动它才发现真不是开玩笑,我已经进不去Gnome桌面了!!! 解决办法: 1,以root身份进入shel ...

  4. 编译原理-First集和Follow集

    刚学first集和follow集的时候,如果上课老师没有讲明白或者自己没听明白,自己看的时候还真是有点难理解,不过结合着具体的题目可以理解的更快. 先看一下两种集合的求法: First集合的求法:   ...

  5. day02.2-常用Linux命令整理

    Linux命令语法格式:   命令    [选项]    [参数] 1). 命令:告诉Linux操作系统执行什么: 2). 选项:说明命令的运行方式.选项部分是以字符‘-’开始的: 3). 参数:说明 ...

  6. python3查询mysql数据

    python3不支持MySQLdb,代替的是import pymysql 连接数据库查表: import pymysqlconn= pymysql.connect( host='xx.xx.xx.xx ...

  7. 「BZOJ3065」带插入区间第K小值 替罪羊树×线段树

    题目描述 从前有\(n\)只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力\(a_i\).跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理性愉悦一下,查询区间\(k\)小值.他 ...

  8. 数据结构20:KMP算法(快速模式匹配算法)详解

    通过上一节的介绍,学习了串的普通模式匹配算法,大体思路是:模式串从主串的第一个字符开始匹配,每匹配失败,主串中记录匹配进度的指针 i 都要进行 i-j+1 的回退操作(这个过程称为“指针回溯”),同时 ...

  9. J.U.C AQS(abstractqueuedssynchronizer--同步器)

    J.U.C AQS(abstractqueuedssynchronizer--同步器)   同步器是用来构建锁和其他同步组件的基础框架,它的实现主要依赖一个int成员变量来表示同步状态以及通过一个FI ...

  10. flask 坑

    no python application found, check your startup logs for errors 日志里面报类似于“Mon Mar 23 10:26:49 2015 – ...