Quartz监听器

Posted Tang.Mr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Quartz监听器相关的知识,希望对你有一定的参考价值。

1.Quartz监听器

1.1.概念

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

1.2.JobListener监听器的使用

1.JobListener源码

JobListener是一个接口,它内部有四个方法。详细解析如下所示;
JobListener用于监听任务,通常需要被监听的任务类实现该接口

public interface JobListener 

    /**
     * 用于获取该JobListener的名称
     */
    String getName();

    /**
     * scheduler在JobDetail将要被执行时调用这个方法【JobDetail执行前】
     * @see #jobExecutionVetoed(JobExecutionContext)
     */
    void jobToBeExecuted(JobExecutionContext context);

    /**
     * scheduler在JobDetail即将被执行,但又被TriggerListener否决时会调用该方法
     * @see #jobToBeExecuted(JobExecutionContext)
     */
    void jobExecutionVetoed(JobExecutionContext context);

    
    /**
     * scheduler在JobDetail被执行后调用这个方法
     */
    void jobWasExecuted(JobExecutionContext context,JobExecutionException jobException);

2.使用演示案例

创建任务类:HelloJobToListener
创建任务调度类:HelloSchedulerDemoListener
创建job监听类:MyJobListener
任务类实现Job接口,并重写execute方法;
任务调度类创建任务执行实例和触发器与调度器进行绑定。并设置对job的监听【全局监听,局部监听】
job监听类实现JobListener接口,重写对应的方法。

HelloJobToListener.java

/**
 * @Author ScholarTang
 * @Date 2021/7/13 19:47
 * @Desc 任务类
 */
@Slf4j
public class HelloJobToListener implements Job 
    @Override
    public void execute(JobExecutionContext context) 
        log.info(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + " | 任务被执行了");
    

MyJobListener.java

/**
 * @Author ScholarTang
 * @Date 2021/7/13 19:53
 * @Desc JobListener
 */
@Slf4j
public class MyJobListener implements JobListener 
    @Override
    public String getName() 
        String name = this.getClass().getSimpleName();
        log.info("当前JobListener的名称为:" + name);
        return name;
    

    @Override
    public void jobToBeExecuted(JobExecutionContext context) 
        String name = context.getJobDetail().getJobClass().getName();
        log.info("当前Job的名称为:" + name + ",JobDetail将要被执行了...");
    

    @Override
    public void jobExecutionVetoed(JobExecutionContext context) 
        String name = context.getJobDetail().getJobClass().getName();
        log.info("当前Job的名称为:" + name + ",JobDetail将要被执,但被TriggerListener否决...");
    

    @Override
    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) 
        String name = context.getJobDetail().getJobClass().getName();
        log.info("当前Job的名称为:" + name + ",JobDetail执行完成了...");
    

HelloSchedulerDemoListener.java

/**
 * @Author ScholarTang
 * @Date 2021/7/13 19:55
 * @Desc 调度器
 */
public class HelloSchedulerDemoListener 
    public static void main(String[] args) throws SchedulerException 
        //通过调度器工厂构建调度器实例
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        //通过JobBuilder构建JobDetail
        JobDetail jobDetail = JobBuilder.newJob(HelloJobToListener.class)
                .withIdentity("job1", "group1")
                .build();
        //通过TriggerBuilder构建Trigger
        CronTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger1", "group1")
                .startNow()
                .withSchedule(CronScheduleBuilder.cronSchedule("3 * * * * ?"))
                .build();
        //调度器绑定JobDetail和Trigger
        scheduler.scheduleJob(jobDetail, trigger);
        //绑定job监听
        //1.全局绑定,所有的job在被调度的时候都会被监听
        //scheduler.getListenerManager().addJobListener(new MyJobListener(), EverythingMatcher.allJobs());
        //2.局部监听,用来监听指定的job
        scheduler.getListenerManager().addJobListener(new MyJobListener(), KeyMatcher
                //jobKey中的name参数和group参数对应的就是任务实例【JobDetail】的name和group
                .keyEquals(JobKey.jobKey("job1","group1")));
        //开启调度
        scheduler.start();
    

3.执行结果

1.3.TriggerListener监听器的使用

任务调度过程中,与触发器Trigger相关的事件包括:触发器触发,触发器未正常触发,触发器触发完成

1.TriggerListener源码
public interface TriggerListener 

    /**
     * 用于触发器的名称
     */
    String getName();

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

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

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

    /**
     * Trigger被触发并完成了Job的执行,scheduler调用这个方法
     */
    void triggerComplete(Trigger trigger, JobExecutionContext context,
            CompletedExecutionInstruction triggerInstructionCode);


2.使用演示案例

创建任务类:HelloJobToTrigger
创建任务调度类:HelloSchedulerDemoTrigger
创建Trigger监听类:MyTriggerListener

HelloJobToTrigger.java

/**
 * @Author ScholarTang
 * @Date 2021/7/13 下午10:03
 * @Desc 任务类
 */
@Slf4j
public class HelloJobToTrigger implements Job 
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException 
        log.info(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " | 任务被执行...");
    

MyTriggerListener.java

/**
 * @Author ScholarTang
 * @Date 2021/7/13 下午10:05
 * @Desc TriggerListener
 */

@Slf4j
public class MyTriggerListener implements TriggerListener 
    @Override
    public String getName() 
        String simpleName = this.getClass().getSimpleName();
        return simpleName;
    

    @Override
    public void triggerFired(Trigger trigger, JobExecutionContext jobExecutionContext) 
        String name = trigger.getKey().getName();
        log.info(name + " | Job上的execute()方法将被执行时,Scheduler就调用该方法");
    

    @Override
    public boolean vetoJobExecution(Trigger trigger, JobExecutionContext jobExecutionContext) 
        boolean temp = false;
        String name = trigger.getKey().getName();
        log.info(name + " | Job将要被执行由Scheduler调用这个方法。Trigger Listener给了一个选择去否决Job的执行为" + (temp ? "为此次Trigger触发" : "不为此次Trigger触发"));
        return temp;
    

    @Override
    public void triggerMisfired(Trigger trigger) 
        String name = trigger.getKey().getName();
        log.info(name + " | scheduler调用这个方法是在Trigger错过触发时调用该方法");
    

    @Override
    public void triggerComplete(Trigger trigger, JobExecutionContext jobExecutionContext, Trigger.CompletedExecutionInstruction completedExecutionInstruction) 
        String name = trigger.getKey().getName();
        log.info(name + " | Trigger被触发并完成了Job的执行,scheduler调用这个方法");
    

HelloSchedulerDemoTrigger.java

/**
 * @Author ScholarTang
 * @Date 2021/7/13 下午10:05
 * @Desc 调度器
 */

public class HelloSchedulerDemoTrigger 
    public static void main(String[] args) throws SchedulerException 
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

        JobDetail jobDetail = JobBuilder.newJob(HelloJobToTrigger.class)
                .withIdentity("job1", "group1")
                .build();

        CronTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger1", "group1")
                .startNow()
                .withSchedule(CronScheduleBuilder.cronSchedule("3 * * * * ?"))
                .build();

        scheduler.scheduleJob(jobDetail, trigger);
        //全局监听
        scheduler.getListenerManager().addTriggerListener(new MyTriggerListener(), EverythingMatcher.allTriggers());
        //局部监听
        //scheduler.getListenerManager().addTriggerListener(new MyTriggerListener(), KeyMatcher.keyEquals(TriggerKey.triggerKey("trigger1", "group1")));
        scheduler.start();
    

3.执行结果

1.4.Scheduler Listener监听器的使用

1.Scheduler Listener源码
public interface SchedulerListener 
    /**
     * 用于部署Job Detail时调用
     */
    void jobScheduled(Trigger trigger);

    /**
     * 用于卸载JobDetail时调用
     */
    void jobUnscheduled(TriggerKey triggerKey);

    /**
     * 当一个Trigger来到了再也不会触发的状态时调用这个方法。除非这个Job已设置成了持久性,否则它就会中scheduler中移除
     */
    void triggerFinalized(Trigger trigger);

    /**
     * scheduler调用这个方法时发生在一个Trigger被暂停时调用。
     */
    void triggerPaused(TriggerKey triggerKey);

    /**
     * scheduler调用这个方法时发生在一个Trigger组被暂停时调用。
     */
    void triggersPaused(String triggerGroup);
    
    /**
     * scheduler调用这个方法发生在为一个Trigger从暂停中恢复时
     */
    void triggerResumed(TriggerKey triggerKey);

    /**
     * scheduler调用这个方法发生在为一个Trigger组从暂停中恢复时
     */
    void triggersResumed(String triggerGroup);

    /**
     * 添加任务时被调用
     */
    void jobAdded(JobDetail jobDetail);
    
    /**
     * 删除任务时被调用
     */
    void jobDeleted(JobKey jobKey);
    
    /**
     * 暂停任务时被调
     */
    void jobPaused(JobKey jobKey);

    /**
     * 暂停任务组时被调用
     */
    void jobsPaused(String jobGroup);
    
    /**
     * 恢复任务时被调用
     */
    void jobResumed(JobKey jobKey);

    /**
     * 恢复任务组时被调用
     */
    void jobsResumed(String jobGroup);

    /**
     * 在scheduler的政策运行期间发生严重错误时被调用
     */
    void schedulerError(String msg, SchedulerException cause);

    /**
     * 在scheduler处于挂载状态时被调用
     */
    void schedulerInStandbyMode();

    /**
     * 在scheduler开启时被调用
     */
    void schedulerStarted();
    
    /**
     * 当调度程序启动时调用该方法
     */
    void schedulerStarting();
    
    /**
     * 当scheduler关闭时调用该方法
     */
    void schedulerShutdown();
    
    /**
     * 当调度程序关闭时调用
     */
    void schedulerShuttingdown();

    /**
     * 当scheduler中的数据被清除时,调用该方法
     */
    void schedulingDataCleared();

2.使用演示案例

HelloJobToScheduler.java

/**
 * @Author ScholarTang
 * @Date 2021/7/13 下午10:03
 * @Desc 任务类
 */
@Slf4j
public class HelloJobToScheduler implements Job 
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException 
        log.info(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " | 任务被执行...");
    

MySchedulerListener.java

/**
 * @Author ScholarTang
 * @Date 2021/7/13 下午10:05
 * @Desc TriggerListener
 */

@Slf4j
public class MySchedulerListener implements SchedulerListener 

    @Override
    public void jobScheduled(Trigger trigger) 
        log.info(trigger.getKey().getName() + " | 用于部署Job Detail时调用");
    

    @Override
    public void jobUnscheduled(TriggerKey triggerKey) 
        log.info(triggerKey.getName() + " | 用于卸载JobDetail时调用");
    

    @Override
    public void triggerFinalized(Trigger trigger) 
        log.info(trigger.getKey().getName() + " | 当一个Trigger来到了再也不会触发的状态时调用这个方法。除非这个Job已设置成了持久性,否则它就会中scheduler中移除");
    

    @Override
    public void triggerPaused(TriggerKey triggerKey) 
        log.info(triggerKey.getName() + " | scheduler调用这个方法时发生在一个Trigger被暂停时调用。");
    

    @Override
    public void triggersPaused(String triggerGroup) 
        log.info(triggerGroup + " | scheduler调用这个方法时发生在一个Trigger组被暂停时调用。");
    

    @Override
    public void triggerResumed(TriggerKey triggerKey) 
        log.info(triggerKey.getName() + " | scheduler调用这个方法发生在为一个Trigger从暂停中恢复时");
    

    @Override
    public void triggersResumed(String triggerGroup) 
        log.info(triggerGroup + " | scheduler调用这个方法发生在为一个Trigger组从暂停中恢复时");
    

    @Override
    public void jobAdded(JobDetail jobDetail) 
        log.info("添加任务时被调用");
    

    @Override
    public void jobDeleted(JobKey jobKey) 
        log.info("删除任务时被调用");
    

    @Override
    public void jobPaused(JobKey jobKey) 
        log.info("暂停任务时被调");
    

    @Override
    public void jobsPaused(String jobGroup) 
        log.info("暂停任务组时被调用");
    

    @Override
    public void jobResumed(JobKey jobKey) 
        log.info("恢复任务时被调用");
    

    @Override
    public void jobsResumed(String jobGroup) 
        log.info("恢复任务组时被调用");
    

    @Override
    public void schedulerError(String msg, SchedulerException cause) 
        log.info("在scheduler的政策运行期间发生严重错误时被调用");
    

    @Override
    public void schedulerInStandbyMode() 
        log.info("在scheduler处于挂载状态时被调用");
    

    @Override
    public void schedulerStarted() 
        log.info("在scheduler开启时被调用");
    

    @Override
    public void schedulerStarting() 
        log.info("当调度程序启动时调用该方法");
    

    @Override
    public void schedulerShutdown() 
        log.info("当scheduler关闭时调用该方法");
    

    @Override
    public void schedulerShuttingdown() 
        log.info("当调度程序关闭时调用");
    

    @Override
    public void schedulingDataCleared() 
        log.info以上是关于Quartz监听器的主要内容,如果未能解决你的问题,请参考以下文章

Quartz监听器

Quartz监听器

Java 鼠标事件监听MouseListener

quartz的框架特征

Quartz入门 监听器Listener

quartz2.3.0job任务监听器,监听任务执行前后取消手动处理方法