Quartz学习总结之监听器Listerner

参考地址:https://www.cnblogs.com/mengrennwpu/p/7191229.html

1. 概述

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

2、JobListener简介

       JobListener 可用于监听定时任务执行的事,并在定时任务执行前后做一些自定义操作,类似于java 切面编程的环绕通知。需要注意的是quartz 2.x系列,监听器已不再进行持久化操作,自然也就没有分布式监听这一说了。在quartz 1.x 时, 数据库表还有监听器相关的表。

       任务调度过程中,与任务Job相关的事件包括:job开始要执行的提示;job执行完成的提示等。其接口如下:

public interface JobListener {

    // 监听器名称
    public String getName();

    // 定时任务执行前执行, 相当于切面编程中的前置通知
    public void jobToBeExecuted(JobExecutionContext context);

    // JobDetail即将被执行,但又被TriggerListerner否决时会调用该方法
    public void jobExecutionVetoed(JobExecutionContext context);

    // 定时任务执行后执行, 相当于切面编程中的后置通知
    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException);

}

第一种创建JobListener的方法是实现JobListener接口,另一种是继承JobListenerSupport类, 只需实现自己关注的方法即可

package org.quartz.listeners;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class JobListenerSupport implements JobListener {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    public JobListenerSupport() {
    }

    protected Logger getLog() {
        return this.log;
    }

    public void jobToBeExecuted(JobExecutionContext context) {
    }

    public void jobExecutionVetoed(JobExecutionContext context) {
    }

    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
    }
}

3、自定义JobListener

3.1 新建Job

package com.zdw.zixue.job;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class ListenerJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("---测试JobListener的Job---");
    }
}

3.2 自定义JobListener

package com.zdw.zixue.listener;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;

/**
 * Create By zdw on 2019/9/26
 */
public class MyJobListener implements JobListener {
    @Override
    public String getName() {
        String simpleName = getClass().getSimpleName();
        System.out.println("自定义监听器名称:"+simpleName);
        return simpleName;
    }

    @Override
    public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {
        String name = jobExecutionContext.getJobDetail().getKey().getName();
        System.out.println(name+"定时任务执行了");
    }

    @Override
    public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {
        String name = jobExecutionContext.getJobDetail().getKey().getName();
        System.out.println(name+"定时任务快要执行时,但又TriggerListerner否决");
    }

    @Override
    public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {
        String name = jobExecutionContext.getJobDetail().getKey().getName();
        System.out.println(name+"定时任务执行完成了");
    }
}

3.3 调度器的创建

package com.zdw.zixue.quartz;

import com.zdw.zixue.job.ListenerJob;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import static org.quartz.DateBuilder.futureDate;

/**
 * 该类是Quartz的服务类,用来创建程序调度器,JobDetail,Trigger等
 */
public class QuartzServerForJobListener {

    //创建调度容器Scheduler
    public static Scheduler createScheduler() throws SchedulerException {
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        return scheduler;
    }

    //创建JobDetail
    public static JobDetail createJobDetail(String jobName, String jobGroup){
        JobDetail jobDetail = JobBuilder.newJob(ListenerJob.class)//设置执行任务的类
                .withIdentity(jobName, jobGroup)//job名称与job组名称组成Scheduler中任务的唯一标识
                .build();//构建
        return jobDetail;
    }

    //创建trigger
    public static Trigger createTrigger(String triggerName, String triggerGroup){
        SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
                .withIdentity(triggerName, triggerGroup)trigger名称与trigger组名称组成Scheduler中任务的唯一标识
                .startAt(futureDate(2, DateBuilder.IntervalUnit.SECOND))//2秒后执行,并且只执行一次
                .withSchedule(SimpleScheduleBuilder.simpleSchedule())
                .build();//构建

        return simpleTrigger;
    }
}

3.4 调度器的执行及绑定监听器

package com.zdw.zixue.test;

import com.zdw.zixue.listener.MyJobListener;
import com.zdw.zixue.quartz.QuartzServer;
import com.zdw.zixue.quartz.QuartzServerForJobListener;
import org.quartz.*;
import org.quartz.impl.matchers.EverythingMatcher;
import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.impl.matchers.KeyMatcher;

public class ListenerJobTest {
    public static void main(String[] args) throws SchedulerException, InterruptedException {
        Scheduler scheduler = QuartzServerForJobListener.createScheduler();//创建调度器
        //创建两个JobDetail
        JobDetail jobDetail = QuartzServerForJobListener.createJobDetail("listenerJob1","listenerGroup1");//创建任务
        JobDetail jobDetail2 = QuartzServerForJobListener.createJobDetail("listenerJob2","listenerGroup2");//创建任务
        //创建两个Trigger
        Trigger trigger = QuartzServerForJobListener.createTrigger("listenerTrigger1","listenerTriggerGroup1");//创建触发器
        Trigger trigger2 = QuartzServerForJobListener.createTrigger("listenerTrigger2","listenerTriggerGroup2");//创建触发器

        //构建调度任务
        scheduler.scheduleJob(jobDetail,trigger);
        scheduler.scheduleJob(jobDetail2,trigger2);

        //创建并注册一个全局的Job Listener,监听所有的Job,注册监听器到调度器
        scheduler.getListenerManager().addJobListener(new MyJobListener(), EverythingMatcher.allJobs());

        //创建一个只监听listenerJob1的监听器
        //scheduler.getListenerManager().addJobListener(new MyJobListener(),KeyMatcher.keyEquals(JobKey.jobKey("listenerJob1","listenerGroup1")));

        //开启任务
        scheduler.start();
        //5s后关闭调度器
        Thread.sleep(50000);

        scheduler.shutdown();
    }
}

第一次是创建的全局监听器,执行结果:

listenerJob1定时任务执行了
listenerJob2定时任务执行了
---测试JobListener的Job---
---测试JobListener的Job---
listenerJob1定时任务执行完成了
listenerJob2定时任务执行完成了

注释掉上面的创建监听器的代码,放开注释掉的代码,那就是创建的只监听listenerJob1的监听器,结果:

listenerJob1定时任务执行了
---测试JobListener的Job---
---测试JobListener的Job---
listenerJob1定时任务执行完成了

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

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

scheduler.getListenerManager().addJobListener(new MyJobListener(), GroupMatcher.jobGroupEquals("listenerGroup1"));

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

scheduler.getListenerManager().addJobListener(new MyJobListener(), OrMatcher.or(GroupMatcher.jobGroupEquals("listenerGroup1"), GroupMatcher.jobGroupEquals("listenerGroup2")));

 

4.TriggerListener

       TriggerListner 用于监听触发器的相关创建,用于在触发器触发前后做一些自定义操作。quartz 中TriggerListener的设计思想和JobListener 的设计思想如出一辙,和JobListener 类似,quartz 2.x 也不再进行持久化操作。

       quartz 提供了两种方式自定义自己的TriggerListener,一种是实现TriggerListener接口,需要实现所有Listener 自定义的方法;另一种是继承TriggerListenerSupport类,只需实现自己关注的方法即可。 

       任务调度过程中,与触发器Trigger相关的事件包括:触发器触发、触发器未正常触发、触发器完成等。TriggerListener的接口如下:

public interface TriggerListener {

    // 返回trigger名称
    String getName();

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

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

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

    // 触发器关联定时任务完成后调用此方法
    void triggerComplete(Trigger trigger, JobExecutionContext context, CompletedExecutionInstruction triggerInstructionCode);

}

4.1 创建Job

package com.zdw.zixue.job;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class ListenerTrigger implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("---测试TriggerListener的Job---");
    }
}

4.2 创建自定义的TriggerListener

package com.zdw.zixue.listener;

import org.quartz.*;

public class MyTriggerListener implements TriggerListener {

    @Override
    public String getName() {
        return "myTriggerListener";//这里不能返回空
    }

    @Override
    public void triggerFired(Trigger trigger, JobExecutionContext jobExecutionContext) {
        String triggerName = trigger.getKey().getName();
        System.out.println(triggerName+"触发器被触发了");
    }

    @Override
    public boolean vetoJobExecution(Trigger trigger, JobExecutionContext jobExecutionContext) {
        return false;
    }

    @Override
    public void triggerMisfired(Trigger trigger) {

    }

    @Override
    public void triggerComplete(Trigger trigger, JobExecutionContext jobExecutionContext, Trigger.CompletedExecutionInstruction completedExecutionInstruction) {
        String triggerName = trigger.getKey().getName();
        System.out.println(triggerName+"触发器完成了------------");
    }
}

4.3 调度器

package com.zdw.zixue.quartz;

import com.zdw.zixue.job.ListenerJob;
import com.zdw.zixue.job.ListenerTrigger;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import static org.quartz.DateBuilder.futureDate;

/**
 * 该类是Quartz的服务类,用来创建程序调度器,JobDetail,Trigger等
 */
public class QuartzServerForTriggerListener {

    //创建调度容器Scheduler
    public static Scheduler createScheduler() throws SchedulerException {
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        return scheduler;
    }

    //创建JobDetail
    public static JobDetail createJobDetail(String jobName, String jobGroup){
        JobDetail jobDetail = JobBuilder.newJob(ListenerTrigger.class)//设置执行任务的类
                .withIdentity(jobName, jobGroup)//job名称与job组名称组成Scheduler中任务的唯一标识
                .build();//构建
        return jobDetail;
    }

    //创建trigger
    public static Trigger createTrigger(String triggerName, String triggerGroup){
        SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
                .withIdentity(triggerName, triggerGroup)trigger名称与trigger组名称组成Scheduler中任务的唯一标识
                .startAt(futureDate(2, DateBuilder.IntervalUnit.SECOND))//2秒后执行,并且只执行一次
                .withSchedule(SimpleScheduleBuilder.simpleSchedule())
                .build();//构建

        return simpleTrigger;
    }
}

4.4 调度器的执行及绑定监听器

package com.zdw.zixue.test;

import com.zdw.zixue.listener.MyJobListener;
import com.zdw.zixue.listener.MyTriggerListener;
import com.zdw.zixue.quartz.QuartzServerForJobListener;
import com.zdw.zixue.quartz.QuartzServerForTriggerListener;
import org.quartz.*;
import org.quartz.impl.matchers.EverythingMatcher;
import org.quartz.impl.matchers.KeyMatcher;

public class ListenerTriggerTest {
    public static void main(String[] args) throws SchedulerException, InterruptedException {
        Scheduler scheduler = QuartzServerForTriggerListener.createScheduler();//创建调度器
        //创建两个JobDetail
        JobDetail jobDetail = QuartzServerForTriggerListener.createJobDetail("listenerJob1","listenerGroup1");//创建任务
        JobDetail jobDetail2 = QuartzServerForTriggerListener.createJobDetail("listenerJob2","listenerGroup2");//创建任务
        //创建两个Trigger
        Trigger trigger = QuartzServerForTriggerListener.createTrigger("listenerTrigger1","listenerTriggerGroup1");//创建触发器
        Trigger trigger2 = QuartzServerForTriggerListener.createTrigger("listenerTrigger2","listenerTriggerGroup2");//创建触发器

        //构建调度任务
        scheduler.scheduleJob(jobDetail,trigger);
        scheduler.scheduleJob(jobDetail2,trigger2);

        //创建并注册一个全局的Trigger Listener,监听所有的Trigger,注册监听器到调度器
        scheduler.getListenerManager().addTriggerListener(new MyTriggerListener(), EverythingMatcher.allTriggers());

        // 创建并注册一个局部的Trigger Listener
        //scheduler.getListenerManager().addTriggerListener(new MyTriggerListener(), KeyMatcher.keyEquals(TriggerKey.triggerKey("listenerTrigger1", "listenerTriggerGroup1")));
        //开启任务
        scheduler.start();
        //5s后关闭调度器
        Thread.sleep(5000);

        scheduler.shutdown();
    }
}

上面代码种,是全局的监听器,执行结果:

listenerTrigger1触发器被触发了
listenerTrigger2触发器被触发了
---测试TriggerListener的Job---
---测试TriggerListener的Job---
listenerTrigger2触发器完成了------------
listenerTrigger1触发器完成了------------

放开上面的注释,并注释掉上面那个全局监听的代码,执行结果:

listenerTrigger1触发器被触发了
---测试TriggerListener的Job---
---测试TriggerListener的Job---
listenerTrigger1触发器完成了------------

 

5. SchedulerListener

       SchedulerListener 是用于监控调度器scheduler 中添加,删除定时任务或触发器等操作。和JobListener,TriggerListener类似,但又有不同。SchedulerListener 全局唯一,也就是说一个Scheduler 只能配置一个SchedulerListener 监听器。

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

       和JobListener/TriggerListener类似,自定义SchedulerListener 需要实现SchedulerListener接口或继承SchedulerListenerSupport,并重写关注的方法。这里推荐使用第二种方式,因为第一种方式需要实现方法太多。
       SchedulerListener 定义的接口方法,每一个方法都是监听对应的Scheduler中定义的方法。
       SchedulerListener 也不会持久化到数据库,更不支持分布式,需要每次启动应用时注册。
SchedulerListener的接口如下:

public interface SchedulerListener {
    //用于部署JobDetail时调用
    public void jobScheduled(Trigger trigger);
    //用于卸载JobDetail时调用
    public void jobUnscheduled(String triggerName, String triggerGroup);
    //当一个 Trigger 来到了再也不会触发的状态时调用这个方法。除非这个 Job 已设置成了持久性,否则它就会从 Scheduler 中移除。
    public void triggerFinalized(Trigger trigger);
    //Scheduler 调用这个方法是发生在一个 Trigger 或 Trigger 组被暂停时。假如是 Trigger 组的话,triggerName 参数将为 null。
    public void triggersPaused(String triggerName, String triggerGroup);
    //Scheduler 调用这个方法是发生成一个 Trigger 或 Trigger 组从暂停中恢复时。假如是 Trigger 组的话,假如是 Trigger 组的话,triggerName 参数将为 null
    public void triggersResumed(String triggerName, String triggerGroup);
    //当一个或一组 JobDetail 暂停时调用这个方法
    public void jobsPaused(String jobName, String jobGroup);
    //当一个或一组 Job 从暂停上恢复时调用这个方法。假如是一个 Job 组,jobName 参数将为 null
    public void jobsResumed(String jobName, String jobGroup);
    //在 Scheduler 的正常运行期间产生一个严重错误时调用这个方法
    public void schedulerError(String msg, SchedulerException cause);
    //当Scheduler 开启时,调用该方法
    public void schedulerStarted();
    //当Scheduler处于StandBy模式时,调用该方法
    public void schedulerInStandbyMode();
    //当Scheduler停止时,调用该方法
    public void schedulerShutdown();
    //当Scheduler中的数据被清除时,调用该方法
    public void schedulingDataCleared();
}

5.1 创建Job

package com.zdw.zixue.job;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class SchedulerListenerJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("---测试SchedulerListener的Job---");
    }
}

5.2 创建自定义的SchedulerListener

package com.zdw.zixue.listener;

import org.quartz.*;

/**
 * Create By zdw on 2019/9/26
 */
public class MyShcedulerListener implements SchedulerListener {

    @Override
    public void jobScheduled(Trigger trigger) {
        String jobName = trigger.getJobKey().getName();
        System.out.println(jobName+"创建了一个JobDetail");
    }

    @Override
    public void jobUnscheduled(TriggerKey triggerKey) {

    }

    @Override
    public void triggerFinalized(Trigger trigger) {

    }

    @Override
    public void triggerPaused(TriggerKey triggerKey) {

    }

    @Override
    public void triggersPaused(String s) {

    }

    @Override
    public void triggerResumed(TriggerKey triggerKey) {

    }

    @Override
    public void triggersResumed(String s) {

    }

    @Override
    public void jobAdded(JobDetail jobDetail) {

    }

    @Override
    public void jobDeleted(JobKey jobKey) {

    }

    @Override
    public void jobPaused(JobKey jobKey) {

    }

    @Override
    public void jobsPaused(String s) {

    }

    @Override
    public void jobResumed(JobKey jobKey) {

    }

    @Override
    public void jobsResumed(String s) {

    }

    @Override
    public void schedulerError(String s, SchedulerException e) {

    }

    @Override
    public void schedulerInStandbyMode() {

    }

    @Override
    public void schedulerStarted() {
        System.out.println("---调度器开启了---");
    }

    @Override
    public void schedulerStarting() {
        System.out.println("---调度器开启ing---");
    }

    @Override
    public void schedulerShutdown() {
        System.out.println("---调度器关闭了---");
    }

    @Override
    public void schedulerShuttingdown() {
        System.out.println("---调度器关闭ing---");
    }

    @Override
    public void schedulingDataCleared() {

    }
}

5.3 创建调度器

package com.zdw.zixue.quartz;

import com.zdw.zixue.job.ListenerTrigger;
import com.zdw.zixue.job.SchedulerListenerJob;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import static org.quartz.DateBuilder.futureDate;

/**
 * 该类是Quartz的服务类,用来创建程序调度器,JobDetail,Trigger等
 */
public class QuartzServerForSchedulerListener {

    //创建调度容器Scheduler
    public static Scheduler createScheduler() throws SchedulerException {
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        return scheduler;
    }

    //创建JobDetail
    public static JobDetail createJobDetail(String jobName, String jobGroup){
        JobDetail jobDetail = JobBuilder.newJob(SchedulerListenerJob.class)//设置执行任务的类
                .withIdentity(jobName, jobGroup)//job名称与job组名称组成Scheduler中任务的唯一标识
                .build();//构建
        return jobDetail;
    }

    //创建trigger
    public static Trigger createTrigger(String triggerName, String triggerGroup){
        SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
                .withIdentity(triggerName, triggerGroup)trigger名称与trigger组名称组成Scheduler中任务的唯一标识
                .startAt(futureDate(2, DateBuilder.IntervalUnit.SECOND))//2秒后执行,并且只执行一次
                .withSchedule(SimpleScheduleBuilder.simpleSchedule())
                .build();//构建

        return simpleTrigger;
    }
}

5.4 调度器执行及绑定监听器

package com.zdw.zixue.test;

import com.zdw.zixue.listener.MyShcedulerListener;
import com.zdw.zixue.listener.MyTriggerListener;
import com.zdw.zixue.quartz.QuartzServerForJobListener;
import org.quartz.*;
import org.quartz.impl.matchers.KeyMatcher;

public class SchedulerTriggerTest {
    public static void main(String[] args) throws SchedulerException, InterruptedException {
        Scheduler scheduler = QuartzServerForJobListener.createScheduler();//创建调度器
        //创建JobDetail
        JobDetail jobDetail = QuartzServerForJobListener.createJobDetail("listenerJob1","listenerGroup1");//创建任务
        //创建Trigger
        Trigger trigger = QuartzServerForJobListener.createTrigger("listenerTrigger1","listenerTriggerGroup1");//创建触发器

        //构建调度任务
        scheduler.scheduleJob(jobDetail,trigger);

        //创建SchedulerListener,监听所有的Trigger,注册监听器到调度器
        scheduler.getListenerManager().addSchedulerListener(new MyShcedulerListener());

        //移除对应的SchedulerListener
        //scheduler.getListenerManager().removeSchedulerListener(new MyShcedulerListener());
        //开启任务
        scheduler.start();
        //5s后关闭调度器
        Thread.sleep(5000);

        scheduler.shutdown();
    }
}

执行结果:

---调度器开启ing---
---调度器开启了---
---测试JobListener的Job---
---调度器关闭ing---
---调度器关闭了---

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值