Quartz任务调度快速入门进阶六——Quartz监听器

880 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Quartz监听器

Quartz监听器的概念

Quartz的监听器用于当任务调度中所关注事件发生时,能够及时获取这一事件的通知。类似于任务执行过程中的邮件、短信类的提醒。Quartz监听器主要有JobListener(任务监听器)、TriggerListener(触发器监听器)、SchedulerListener(调度器监听器)三类。

在此之前需要明确两个概念:全局监听器、非全局监听器

  • 全局监听器:能够接收所有的Job/Trigger的事件通知
  • 非全局监听器:只能接收到在其上注册的Job或Trigger的事件,其他的则不会进行监听。

JobListener

任务调度过程中,与任务Job想过的事件包括:Job开始要执行的提示;Job执行完成的提示等

public interface JobListener {
    String getName();
    void jobToBeExecuted(JobExecutionContext context);
    void jobExecutionVetoed(JobExecutionContext context)void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException);
}
  • getName方法:用于获取该JobListener的名称。
  • jobToBeExecuted方法:Scheduler在JobDetail将要被执行时调用这个方法。
  • jobExecutionVetoed方法:Scheduler在JobDetail即将被执行,但又被TriggerListener否决时会调用该方法
  • jobWasExecuted方法:Scheduler在JobDetail被执行之后调用这个方法。

示例: HelloJobListener.java

// 定义任务类
pubic class HelloJobListener implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionExxepyion {
        // 定义时间
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = dateFormat.format(date);
        
        // 定义工作任务内容
        System.out.println("进行数据库备份操作,当前任务执行的时间:"+dateString);
    }
}

创建自定义的JobListener MyJobListener.java

public class MyJobListener implements JobListener {
    @Override
    public String getName() {
        String name = getClass.getSimpleName();
        System.out.println("监听器的名称是:"+name);
        return name;
    }
    
    @Override
    public void jobToBeExecuted(JobExecutionContext context) {
        String jobNname = context.getJobDetail().getKey().getName();
        System.out.println("Job的名称是:"+jobName+",Scheduler在JobDetail将要被执行时调用这个方法");
    }
    
    @Override
    public void jobExecutionVetoed(JobExecutionContext context) {
        String jobNname = context.getJobDetail().getKey().getName();
        System.out.println("Job的名称是:"+jobName+",Scheduler在JobDetail即将被执行,但又被TriggerListener否决时会调用该方法");
    }
    
    @Override
    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
        String jobName = context.getJobDetail().getKey().getName();
        System.out.println("Job的名称是:"+jobName+",Scheduler在JobDetail被执行之后调用这个方法");
    }
} 

执行调度器 HelloSchedulerDemoJobListener.java

public class HelloSchedulerDemoJobListener {
    public static void main(String[] args) throws Exception {
        //1:从工厂中获取任务调度的实例 
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); 
        
        //2:定义一个任务调度实例,将该实例与HelloJob绑定,任务类需要实现Job接口 
        JobDetail job = JobBuilder.newJob(HelloJobSimpleTrigger.class) 
                .withIdentity("job1", "group1") //定义该实例唯一标识 
                .build(); 
        
        //3:定义触发器,马上执行,然后每5秒重复执行一次 
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger1", "group1") // 定义该实例唯一标识 
                .startNow() // 马上执行
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                    .repeatSecondlyForever(5)) // 每隔5秒执行一次
                .build(); 
        
        //4:使用触发器调度任务的执行 
        scheduler.schedulerJob(job, trigger); 
        
        // 创建并注册一个全局的Job Listener
        scheduler.getListenerManager().addJobListener(new MyJobListener(), EverythingMatcher.allJobs());
        
        // 创建并注册一个指定任务的Job Listener
        // scheduler.getListenerManager().addJobListener(new SimpleJobListener(), keyMatcher.keyEquals(JobKey.jobKey("job1", "group1")));
        
        //5:开启 
        scheduler.start();
        
        //6:关闭 
        scheduler.shutdown();  
    }
}

TriggerListener

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

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);
}
  • getName方法:用于获取触发器的名称;
  • triggerFired方法:当与监听器相关联的Trigger被触发,job上的execute()方法就被执行时,Scheduler就调用该方法;
  • vetoJobExecution方法:在Trigger触发后,job将要被执行时由Scheduler调用这个方法。TriggerListener给了一个选择去否决job的执行,假如这个方法返回true,这个job将不会为此次Trigger触发而得到执行;
  • triggerMisfired方法:scheduler调用这个方法是在Trigger错过触发时,应该关注次方法中持续时间长的逻辑:在出现许多错过触发的Trigger时,长逻辑会导致骨牌效应,应该保持该方法尽量的小。
  • triggerComplete方法:Trigger被触发并且完成了job的执行时,Scheduler调用这个方法。

SchedulerListener

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

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