Quartz的监听器

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

        Quartz监听器主要有JobListener、TriggerListener、SchedulerListener三种,顾名思义,分别表示任务、触发器、调度器对应的监听器。三者的使用方法类似,在开始介绍三种监听器之前,需要明确两个概念:全局监听器与非全局监听器,二者的区别在于:
全局监听器能够接收到所有的Job/Trigger的事件通知,
非全局监听器只能接收到在其上注册的Job或Trigger的事件,不在其上注册的Job或Trigger则不会进行监听。

1、JobListener job监听器

在job执行之前,之后或者执行过程中动态去添加一些额外的动作。

  1. 任务调度过程中,与任务Job相关的事件包括:job开始要执行的提示; job执行完成的提示。
  2. JobListener监听器:
public interface JobListener {

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

    // Scheduler在JobDetail将要被执行时调用这个方法.
    void jobToBeExecuted(JobExecutionContext var1);

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

    // Scheduler在JobDetail被执行之后调用这个方法.
    void jobWasExecuted(JobExecutionContext var1, JobExecutionException var2);
}

        3、案例使用JobListener

  • 自定义一个Job
public class HelloJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        //输出当前时间的job
        Date date = new Date();
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = simpleDateFormat.format(date);

        System.out.println("正在进行数据库备份工作,备份数据库的时间是"+dateString);
    }
}
  • 自定义一个JobListener
public class MyListener implements JobListener {
    @Override
    public String getName() {
        String simpleName = this.getClass().getSimpleName();
        System.out.println("监听器的名称是:"+simpleName);
        return simpleName;
    }

    @Override
    public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {

        String name = jobExecutionContext.getJobDetail().getKey().getName();
        System.out.println("Scheduler在jobDetail将要被执行时调用的方法"+name);

    }

    @Override
    public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {

        String name = jobExecutionContext.getJobDetail().getKey().getName();
        System.out.println("job将要被执行,但是又被trigger否决时执行的方法:"+name);

    }

    @Override
    public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {

        String name = jobExecutionContext.getJobDetail().getKey().getName();
        System.out.println("job被执行后调用的方法:"+name);

    }
}
  • 注册监听器到Scheduler
public class HelloSchedulerDemoListener {

    public static void main(String[] args) throws SchedulerException {
        //1:调度器(Scheduler),从工厂中获取调度实例,默认是实例化了new StdSchedulerFactory
        //Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        StdSchedulerFactory stdSchedulerFactory=new StdSchedulerFactory();
        Scheduler scheduler=stdSchedulerFactory.getScheduler();
        //2:任务实例(JobDetail)

        //加载任务类,与HelloJob完成绑定,要求HelloJob实现Job接口
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
                //参数1:任务的名称,(唯一实例)。参数2:任务组的名称
                .withIdentity("job1", "group1")
                .usingJobData("message","打印JobDetail日志")
                .usingJobData("count",0)
                .build();

        //3:触发器(Trigger)
        Trigger trigger = TriggerBuilder.newTrigger()
                //参数1:触发器名称,触发器组的名称
                .withIdentity("trigger1", "group1")
                .startNow()//马上启动
                //使用日历触发器
                .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
              //  .withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatForever().withIntervalInSeconds(5))
                //指定时间启动
                .usingJobData("message","打印Trigger日志")
                .build();

        //4. 使用调度器将触发器和任务jobdetail关联
        Date date = scheduler.scheduleJob(jobDetail, trigger);
        SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("调度器开始调度时间"+dateFormat.format(date));
        // 6. 创建并注册一个全局的Job Listener
        //scheduler.getListenerManager().addJobListener(new MyListener(), EverythingMatcher.allJobs());

        //7. 创建一个局部的Job Listener 所谓的局部就是指定的job
        scheduler.getListenerManager().addJobListener(new MyListener(), KeyMatcher.keyEquals(JobKey.jobKey("job1","group1")));
        //5. 启动触发器
        scheduler.start();

    }
}

2、TriggerListener 触发器监听器

        TriggerListener 有一个TriggerListenerSupport的抽象类,即我们也可以继承这个类,只实现其中的部分业务关注的方法。

  1. 使用方法和JobListener相同,主要是监听触发器的一些情况:任务调度过程中,与触发器Trigger相关的事件包括:触发器触发、触发器未正常触发、触发器完成等。
public interface TriggerListener {

    // 用于获取触发器的名称
    public String getName();

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

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

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

    // Trigger 被触发并且完成了 Job 的执行时,Scheduler 调用这个方法。
    public void triggerComplete(Trigger trigger, JobExecutionContext context,
            int triggerInstructionCode);
}

2、案例 TriggerListener

  • job
  • TriggerListener
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) {
        String triggerName = trigger.getKey().getName();
        System.out.println(triggerName + " 被触发");
    }

    @Override
    public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
        String triggerName = trigger.getKey().getName();
        System.out.println(triggerName + " 没有被触发");
        return true; // true:表示不会执行Job的方法
    }

    @Override
    public void triggerMisfired(Trigger trigger) {
        String triggerName = trigger.getKey().getName();
        System.out.println(triggerName + " 错过触发");
    }

    @Override
    public void triggerComplete(Trigger trigger, JobExecutionContext context,
                                Trigger.CompletedExecutionInstruction triggerInstructionCode) {
        String triggerName = trigger.getKey().getName();
        System.out.println(triggerName + " 完成之后触发");
    }

}
  • Scheduler调度
public class HelloSchedulerDemoListener {

    public static void main(String[] args) throws SchedulerException {
        //1:调度器(Scheduler),从工厂中获取调度实例,默认是实例化了new StdSchedulerFactory
        //Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        StdSchedulerFactory stdSchedulerFactory=new StdSchedulerFactory();
        Scheduler scheduler=stdSchedulerFactory.getScheduler();
        //2:任务实例(JobDetail)

        //加载任务类,与HelloJob完成绑定,要求HelloJob实现Job接口
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
                //参数1:任务的名称,(唯一实例)。参数2:任务组的名称
                .withIdentity("job1", "group1")
                .usingJobData("message","打印JobDetail日志")
                .usingJobData("count",0)
                .build();

        //3:触发器(Trigger)
        Trigger trigger = TriggerBuilder.newTrigger()
                //参数1:触发器名称,触发器组的名称
                .withIdentity("trigger1", "group1")
                .startNow()//马上启动
                //使用日历触发器
                .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
              //  .withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatForever().withIntervalInSeconds(5))
                //指定时间启动
                .usingJobData("message","打印Trigger日志")
                .build();

        //4. 使用调度器将触发器和任务jobdetail关联
        Date date = scheduler.scheduleJob(jobDetail, trigger);
        SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("调度器开始调度时间"+dateFormat.format(date));
        // 6. 创建并注册一个全局的Job Listener
        //scheduler.getListenerManager().addJobListener(new MyListener(), EverythingMatcher.allJobs());

        //7. 创建一个局部的Job Listener 所谓的局部就是指定的job
      //  scheduler.getListenerManager().addJobListener(new MyListener(), KeyMatcher.keyEquals(JobKey.jobKey("job1","group1")));

        // 8. 创建并注册一个全局的Trigger Listener
        scheduler.getListenerManager().addTriggerListener(new MyTriggerListener("simpleTrigger"), EverythingMatcher.allTriggers());

        // 9. 创建并注册一个局部的Trigger Listener
        // scheduler.getListenerManager().addTriggerListener(new MyTriggerListener("simpleTrigger"), KeyMatcher.keyEquals(TriggerKey.triggerKey("trigger1", "group1")));
        //5. 启动触发器
        scheduler.start();

    }
}

3、SchedulerListener 调度监听

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

在接口实现上,可以实现SchedulerListener,也可以继承SchedulerListenerSupport抽象类。

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。参数将为 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();
}

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值