【Quartz】Quartz监听的详细介绍以及使用
目录
主要特性和组件
Quartz定时任务框架的主要特性和组件:
-
调度器(Scheduler):这是Quartz的核心组件,用于管理任务的调度。调度器维护了任务的执行时间表。
-
作业(Job):在Quartz中,作业是由Job接口定义的一个组件,它具体定义了要执行的任务。开发者需要实现这个接口,并定义execute方法,以编写具体的任务逻辑。
-
触发器(Trigger):用于定义任务的执行时间。触发器可以是简单的,如只执行一次或按固定间隔重复执行,也可以是复杂的,如使用cron表达式定义的执行计划。
-
JobDetail:用于定义Job的实例,它与实际的作业执行类关联,并包含作业的各种属性设置。
-
存储:Quartz可以配置为使用不同类型的存储(如内存、数据库等),以保持作业和触发器的状态。这允许任务在应用程序重启后继续执行,也支持集群模式下的作业管理。
-
集群支持:Quartz可以配置为在多个节点上运行,支持负载均衡和故障转移。
-
事务管理:Quartz支持事务,确保任务的执行在失败时能够恢复到稳定状态。
-
监听器(Listeners):Quartz提供了几种监听器,允许在任务的生命周期的不同阶段(如任务执行前后)进行干预。
监听器
Quartz 提供了几种类型的监听器,这些监听器可以挂接到调度器的不同事件和任务执行周期中。通过这些监听器,开发者可以在任务执行的关键时刻执行自定义逻辑,如任务执行前后、触发器触发前后等。下面是 Quartz 主要的几种监听器类型:
-
JobListener:这种类型的监听器关注于作业的生命周期,可以监听作业执行前、执行后以及执行时遇到的任何异常。这允许开发者在作业执行的不同阶段添加日志、异常处理和其他业务逻辑。
- jobToBeExecuted:在 JobDetail 将要被执行时调用。
- jobWasExecuted:在 JobDetail 执行完毕后调用,无论它执行成功还是失败。
- jobExecutionVetoed:在 JobDetail 被触发器触发但在执行之前被拒绝执行时调用。
-
TriggerListener:这种监听器关注于触发器的生命周期。可以在触发器触发作业前后执行自定义逻辑,或者在错过触发时进行处理。
- triggerFired:当与监听器相关联的触发器触发,准备调用作业时调用。
- triggerMisfired:当触发器错过触发时调用。
- triggerComplete:当触发器完成作业的触发后调用。
-
SchedulerListener:这种监听器提供了对调度器事件的监听,如作业/触发器的添加、删除或调度器的错误。
- jobScheduled:当一个新的作业被调度时调用。
- jobUnscheduled:当一个作业被取消调度时调用。
- triggerPaused:当一个或一组触发器被暂停时调用。
- triggerResumed:当一个或一组触发器恢复时调用。
- schedulerError:在调度器的执行中发生错误时调用。
- schedulerStarted 和 schedulerShutdown:当调度器启动和关闭时调用。
这些监听器可以通过实现相应的接口并注册到调度器中,从而实现监控和响应调度器中的各种事件。通过使用这些监听器,可以更好地控制作业执行流程和管理作业的生命周期,也可以实现复杂的业务逻辑和错误处理策略。
JobListener
下面是一个用Java实现的自定义JobListener示例,该监听器会在作业执行前后打印日志,并处理任何在执行期间发生的异常。这样的监听器对于调试或跟踪任务执行的状态非常有用。
首先,需要实现JobListener接口。在这个接口中,我们将覆盖三个方法:jobToBeExecuted(), jobWasExecuted(), 和 jobExecutionVetoed()。这里是具体的实现:
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
public class MyJobListener implements JobListener {
private String name;
public MyJobListener(String name) {
this.name = name;
}
@Override
public String getName() {
// 返回监听器的名称
return name;
}
@Override
public void jobToBeExecuted(JobExecutionContext context) {
// 在作业执行之前调用
String jobName = context.getJobDetail().getKey().toString();
System.out.println("Job " + jobName + " is about to be executed.");
}
@Override
public void jobExecutionVetoed(JobExecutionContext context) {
// 在作业执行被否决时调用
String jobName = context.getJobDetail().getKey().toString();
System.out.println("Execution of job " + jobName + " was vetoed.");
}
@Override
public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
// 在作业执行之后调用
String jobName = context.getJobDetail().getKey().toString();
System.out.println("Job " + jobName + " was executed.");
// 检查作业执行期间是否有异常
if (jobException != null) {
System.err.println("Exception thrown by: " + jobName + " Exception: " + jobException.getMessage());
}
}
}
要在Quartz调度器中使用这个监听器,需要将其注册到调度器上。这里是如何注册监听器的示例:
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.Scheduler;
public class SchedulerExample {
public static void main(String[] args) {
try {
// 获取调度器实例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 创建并注册监听器
MyJobListener listener = new MyJobListener("MyJobListener");
scheduler.getListenerManager().addJobListener(listener);
// 启动调度器(如果还未启动)
if (!scheduler.isStarted()) {
scheduler.start();
}
// 在这里添加作业和触发器
// 为了示例持续运行,等待一段时间
Thread.sleep(60000);
// 关闭调度器
scheduler.shutdown();
} catch (Exception e) {
e.printStackTrace();
}
}
}
在这个例子中,SchedulerExample 类负责创建调度器,注册自定义的JobListener,并启动和关闭调度器。你可以根据自己的需求添加作业和触发器。这样,每当相关的作业即将执行、执行完成或被否决执行时,你的监听器都会得到通知并执行定义的逻辑。
TriggerListener
要创建一个自定义的TriggerListener,你需要实现TriggerListener接口。这个接口包含几个方法,用于在触发器的关键生命周期点进行操作。这些方法包括在触发器触发、错过触发、和完成触发时的处理。
下面是一个实现TriggerListener接口的示例,该示例中的监听器在触发器触发作业之前、作业错过触发时以及触发器完成作业触发后打印消息。这对于监控和调试触发器状态非常有用。
实现 TriggerListener
import org.quartz.Trigger;
import org.quartz.TriggerListener;
import org.quartz.Trigger.CompletedExecutionInstruction;
import org.quartz.JobExecutionContext;
import org.quartz.SchedulerException;
public class MyTriggerListener implements TriggerListener {
private String name;
public MyTriggerListener(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public void triggerFired(Trigger trigger, JobExecutionContext context) {
// 在触发器触发,作业即将执行时调用
System.out.println("Trigger " + trigger.getKey() + " has fired.");
}
@Override
public void triggerMisfired(Trigger trigger) {
// 在触发器错过触发时调用
System.out.println("Trigger " + trigger.getKey() + " has misfired.");
}
@Override
public void triggerComplete(Trigger trigger, JobExecutionContext context,
CompletedExecutionInstruction triggerInstructionCode) {
// 在触发器完成作业触发后调用
System.out.println("Trigger " + trigger.getKey() + " is complete.");
}
@Override
public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
// 在作业即将由触发器触发执行时调用,返回 true 可以阻止作业的执行
return false; // 在这里我们不想阻止作业执行
}
}
注册 TriggerListener 到调度器
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
public class SchedulerExample {
public static void main(String[] args) {
try {
// 获取调度器实例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 创建并注册监听器
MyTriggerListener triggerListener = new MyTriggerListener("MyTriggerListener");
scheduler.getListenerManager().addTriggerListener(triggerListener);
// 启动调度器(如果还未启动)
if (!scheduler.isStarted()) {
scheduler.start();
}
// 在这里添加作业和触发器
// 为了示例持续运行,等待一段时间
Thread.sleep(60000);
// 关闭调度器
scheduler.shutdown();
} catch (SchedulerException | InterruptedException e) {
e.printStackTrace();
}
}
}
在上述示例中,SchedulerExample 类负责创建调度器,注册自定义的TriggerListener,并启动和关闭调度器。这个监听器会在触发器触发、错过、或完成时进行相应的操作,并通过打印信息到控制台来帮助监控触发器的状态。这是一个简单的示例,您可以根据自己的业务需求对其进行修改和扩展。
SchedulerListener
创建一个自定义的SchedulerListener涉及实现SchedulerListener接口,这个接口包含一系列方法,可以在调度器的各种事件发生时执行自定义逻辑。这些事件包括调度器的启动和关闭、作业和触发器的添加和移除、以及调度器出错时的处理。
以下是一个实现SchedulerListener接口的示例,该监听器会在调度器相关事件发生时打印信息到控制台,帮助监控调度器的状态。
实现 SchedulerListener
import org.quartz.SchedulerException;
import org.quartz.SchedulerListener;
import org.quartz.JobDetail;
import org.quartz.Trigger;
public class MySchedulerListener implements SchedulerListener {
@Override
public void jobScheduled(Trigger trigger) {
System.out.println("Job scheduled: " + trigger.getJobKey() + " with trigger " + trigger.getKey());
}
@Override
public void jobUnscheduled(Trigger.Key triggerKey) {
System.out.println("Job unscheduled: " + triggerKey);
}
@Override
public void triggerFinalized(Trigger trigger) {
System.out.println("Trigger finalized and will not fire again: " + trigger.getKey());
}
@Override
public void triggerPaused(Trigger.Key triggerKey) {
System.out.println("Trigger paused: " + triggerKey);
}
@Override
public void triggersPaused(String triggerGroup) {
System.out.println("All triggers of group '" + triggerGroup + "' were paused.");
}
@Override
public void triggerResumed(Trigger.Key triggerKey) {
System.out.println("Trigger resumed: " + triggerKey);
}
@Override
public void triggersResumed(String triggerGroup) {
System.out.println("All triggers of group '" + triggerGroup + "' were resumed.");
}
@Override
public void jobAdded(JobDetail jobDetail) {
System.out.println("Job added: " + jobDetail.getKey());
}
@Override
public void jobDeleted(JobKey jobKey) {
System.out.println("Job deleted: " + jobKey);
}
@Override
public void jobPaused(JobKey jobKey) {
System.out.println("Job paused: " + jobKey);
}
@Override
public void jobsPaused(String jobGroup) {
System.out.println("All jobs in group '" + jobGroup + "' were paused.");
}
@Override
public void jobResumed(JobKey jobKey) {
System.out.println("Job resumed: " + jobKey);
}
@Override
public void jobsResumed(String jobGroup) {
System.out.println("All jobs in group '" + jobGroup + "' were resumed.");
}
@Override
public void schedulerError(String msg, SchedulerException cause) {
System.out.println("Scheduler error: " + msg + ", caused by: " + cause.getMessage());
}
@Override
public void schedulerInStandbyMode() {
System.out.println("Scheduler entered standby mode.");
}
@Override
public void schedulerStarted() {
System.out.println("Scheduler started.");
}
@Override
public void schedulerStarting() {
System.out.println("Scheduler is starting.");
}
@Override
public void schedulerShutdown() {
System.out.println("Scheduler shutdown.");
}
@Override
public void schedulerShuttingDown() {
System.out.println("Scheduler is shutting down.");
}
@Override
public void schedulingDataCleared() {
System.out.println("Scheduling data cleared.");
}
}
注册 SchedulerListener 到调度器
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
public class SchedulerExample {
public static void main(String[] args) {
try {
// 获取调度器实例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 创建并注册监听器
MySchedulerListener schedulerListener = new MySchedulerListener();
scheduler.getListenerManager().addSchedulerListener(schedulerListener);
// 启动调度器(如果还未启动)
if (!scheduler.isStarted()) {
scheduler.start();
}
// 在这里添加作业和触发器
// 为了示例持续运行,等待一段时间
Thread.sleep(60000);
// 关闭调度器
scheduler.shutdown();
} catch (SchedulerException | InterruptedException e) {
e.printStackTrace();
}
}
}
在这个例子中,SchedulerExample 类负责创建调度器,注册自定义的SchedulerListener,并启动和关闭调度器。此监听器将在调度器中发生的各种事件时提供反馈,如作业或触发器的添加、删除、调度器的错误、启动或关闭。这样可以帮助开发者跟踪调度器的操作和状态。
更多推荐



所有评论(0)