天天看点

定时任务调度框架Quartz--JobListeners

文章目录

  • ​​基础监听接口JobListener​​
  • ​​配置全局监听器​​
  • ​​配置局部监听器​​
  • ​​KeyMatcher​​
  • ​​GroupMatcher​​
  • ​​OrMatcher​​
  • ​​EverythingMatcher​​

基础监听接口JobListener

        JobListener接口方法及其源码

方法名 作用
getName 此监听器对象的名称
jobToBeExecuted 在监听的JobDetail实例即将执行之前触发
jobExecutionVetoed Scheduler 在 JobDetail 即将被执行,但又被 TriggerListener 否决了时触发这个方法
jobWasExecuted 在监听的JobDetail实例执行完成后触发
public interface JobListener {
    public String getName();
    public void jobToBeExecuted(JobExecutionContext context);
    public void jobExecutionVetoed(JobExecutionContext context);
    public void jobWasExecuted(JobExecutionContext context,
            JobExecutionException jobException);
}      

        成为一个JobDetail只需要实现JobListener接口即可。下面是我的自定义实现。

public class MyJobListener implements JobListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyJobListener.class);

    @Override
    public String getName() {
        return "myJobListener";
    }

    @Override
    public void jobToBeExecuted(JobExecutionContext context) {
        JobDetail jobDetail = context.getJobDetail();
        //触发前做日志等记录
        LOGGER.error(getName() + "触发对JobDetail[" + jobDetail.hashCode() 
                                + "]执行之前的监听,做预处理");
    }

    @Override
    public void jobExecutionVetoed(JobExecutionContext context) {
        //该JobDetail实例被Trigger否决触发
        JobDetail jobDetail = context.getJobDetail();
        LOGGER.error(getName() + "触发对" + jobDetail.hashCode() + "的Trigger否决监听任务");
    }

    @Override
    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
        JobDetail jobDetail = context.getJobDetail();
        try {
            //触发后做日志等记录,执行时间分析
            LOGGER.error(getName() + "触发对JobDetail[" + jobDetail.hashCode() 
                                                                + "]执行完成之后的监听,做后处理");
            LOGGER.error("调度器名称:" + context.getScheduler().getSchedulerName());
            LOGGER.error("任务名称:" + jobDetail.getKey().getName());
            LOGGER.error("任务分组:" + jobDetail.getKey().getGroup());
            LOGGER.error("触发器TriggerID:" + context.getFireInstanceId());
            LOGGER.error("本次触发完成时间:" + 
                    DateTransformTools.dateToDateStr(context.getFireTime()));
            LOGGER.error("下次触发执行时间:" + 
                    DateTransformTools.dateToDateStr(context.getNextFireTime()));

        } catch (Exception e) {
            LOGGER.error(getName() + "触发对JobDetail[" + jobDetail.hashCode()
                                                                + "]后处理出现异常");
        }
    }
}      

        当然了,也可以扩展JobListenerSupport类,并且只需覆盖你感兴趣的事件

配置全局监听器

        配置全局监听,只需要把JobListener接口实现配置到Scheduler中。

scheduler.getListenerManager().addJobListener(jobListenerImpl);      

        下面是我的测试用例

public static void main(String[] args) {
        try {
            //define the job and bind it to our HelloJob class
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
            scheduler.start();

            JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1").
                    build();

            Trigger trigger = newTrigger().withIdentity("trigger2", "group1")
                    .usingJobData("格言3", "奥特曼猪猪侠闪电小子葫芦娃")
                    .startAt(DateBuilder.todayAt(10, 0, 0))
                    .withSchedule(cronSchedule("0 0/1 11 * * ?").
                            //错过的任务全部忽略
                            withMisfireHandlingInstructionDoNothing())
                    .forJob("job1", "group1").build();

            //添加全局Job监听
            MyJobListener myJobListener = new MyJobListener();
            scheduler.getListenerManager().addJobListener(myJobListener);
            
            //用我们的触发告诉schedule安排工作
            scheduler.scheduleJob(job,trigger);

            //在调用shutdown()之前,你需要给job的触发和执行预留一些时间,比如,你可以调用
            Thread.sleep(1000000000);
            scheduler.shutdown();
        } catch (Exception e) {
            LOGGER.error("an exception was occurred , caused by :{}", e.getMessage());
        }
    }


    public static class HelloJob implements Job {

        @Override
        public void execute(JobExecutionContext context) throws JobExecutionException {
            LOGGER.error("现在是:{},JobInstanceId:{}", 
                       DateTransformTools.dateToDateStr(new Date()), this.hashCode());
        }
    }
}      
定时任务调度框架Quartz--JobListeners

​上述程序目的在10点钟开始执行,每一分钟执行一次定时任务。从实际效果上来看,监听器监听到JobDetail实例的执行。说明自定义的JobListener配置成全局Job监听器成功。​

配置局部监听器

#全局Job监听配置核心代码
scheduler.getListenerManager().addJobListener(jobListenerImpl);      
KeyMatcher

       为单个Job配置监听器,使用JobKey进行匹配。

scheduler.getListenerManager().addJobListener(myJobListener, 
                         KeyMatcher.keyEquals(JobKey.jobKey("job1", "group1")));
                         
//或者直接把JobDetail传进来,这样写
scheduler.getListenerManager().addJobListener(myJobListener, 
                         KeyMatcher.keyEquals(jobDetail.getKey()));      
GroupMatcher

       使用Group进行匹配。下面是对整个叫做“group1”的Job组增加监听器

.getListenerManager().addJobListener(myJobListener, 
                                        GroupMatcher.jobGroupEquals("group1"));      
OrMatcher
.getListenerManager().addJobListener(myJobListener,
                    OrMatcher.or(
                            GroupMatcher.jobGroupEquals("group1"), 
                            GroupMatcher.jobGroupEquals("group2"))
                       );      
EverythingMatcher
scheduler.getListenerManager().addJobListener(myJobListener,EverythingMatcher.allJobs());