目录

主要特性和组件

监听器

JobListener

TriggerListener

实现 TriggerListener

注册 TriggerListener 到调度器 

SchedulerListener

实现 SchedulerListener

注册 SchedulerListener 到调度器


主要特性和组件

Quartz定时任务框架的主要特性和组件:

  1. 调度器(Scheduler):这是Quartz的核心组件,用于管理任务的调度。调度器维护了任务的执行时间表。

  2. 作业(Job):在Quartz中,作业是由Job接口定义的一个组件,它具体定义了要执行的任务。开发者需要实现这个接口,并定义execute方法,以编写具体的任务逻辑。

  3. 触发器(Trigger):用于定义任务的执行时间。触发器可以是简单的,如只执行一次或按固定间隔重复执行,也可以是复杂的,如使用cron表达式定义的执行计划。

  4. JobDetail:用于定义Job的实例,它与实际的作业执行类关联,并包含作业的各种属性设置。

  5. 存储:Quartz可以配置为使用不同类型的存储(如内存、数据库等),以保持作业和触发器的状态。这允许任务在应用程序重启后继续执行,也支持集群模式下的作业管理。

  6. 集群支持:Quartz可以配置为在多个节点上运行,支持负载均衡和故障转移。

  7. 事务管理:Quartz支持事务,确保任务的执行在失败时能够恢复到稳定状态。

  8. 监听器(Listeners):Quartz提供了几种监听器,允许在任务的生命周期的不同阶段(如任务执行前后)进行干预。

监听器

Quartz 提供了几种类型的监听器,这些监听器可以挂接到调度器的不同事件和任务执行周期中。通过这些监听器,开发者可以在任务执行的关键时刻执行自定义逻辑,如任务执行前后、触发器触发前后等。下面是 Quartz 主要的几种监听器类型:

  1. JobListener:这种类型的监听器关注于作业的生命周期,可以监听作业执行前、执行后以及执行时遇到的任何异常。这允许开发者在作业执行的不同阶段添加日志、异常处理和其他业务逻辑。

    • jobToBeExecuted:在 JobDetail 将要被执行时调用。
    • jobWasExecuted:在 JobDetail 执行完毕后调用,无论它执行成功还是失败。
    • jobExecutionVetoed:在 JobDetail 被触发器触发但在执行之前被拒绝执行时调用。
  2. TriggerListener:这种监听器关注于触发器的生命周期。可以在触发器触发作业前后执行自定义逻辑,或者在错过触发时进行处理。

    • triggerFired:当与监听器相关联的触发器触发,准备调用作业时调用。
    • triggerMisfired:当触发器错过触发时调用。
    • triggerComplete:当触发器完成作业的触发后调用。
  3. 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,并启动和关闭调度器。此监听器将在调度器中发生的各种事件时提供反馈,如作业或触发器的添加、删除、调度器的错误、启动或关闭。这样可以帮助开发者跟踪调度器的操作和状态。

更多推荐