06.Quartz 监听器-JobListener

天大地大妈咪最大 提交于 2019-11-28 18:18:52

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

1. JobListener 定义

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

1.1 JobListener 接口定义

public interface JobListener {

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

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

    // TriggerListener 否决了执行时触发
    public void jobExecutionVetoed(JobExecutionContext context);

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

}

1.2 监听器匹配模式

quartz 提供了Matcher 接口用于指定监听器匹配任务的模式, 可具体匹配的定时任务, 或按组进行屁, 亦或者匹配全部的定时任务

 // 监听具体的一个定时任务
KeyMatcher<JobKey> jobKeyMatcher = KeyMatcher.keyEquals(JobKey.jobKey("jobName1", "jobGroupName1"));

// 监听一组定时任务
GroupMatcher<JobKey> jobGroupMatcher = GroupMatcher.groupEquals("jobGroupName");

// 监听所有的任务分组
GroupMatcher<JobKey> allMatcher = GroupMatcher.anyJobGroup();

1.3 注册JobListener


# 1. 创建监听器匹配模式
 KeyMatcher<JobKey> jobKeyMatcher = KeyMatcher.keyEquals(JobKey.jobKey("listenerJob", "jobGroup7"));

# 2. 注册监听器
scheduler.getListenerManager().addJobListener(new MyFirstJobListener(), jobKeyMatcher);

2. 自定义JobListener

由于quartz 2.x 并不会对监听器做持久化操作, 因此笔者使用基于ram 配置的quartz环境.

2.1 实现JobListener接口

必须实现JobListener接口的所有方法,

public class MyFirstJobListener implements JobListener {
    @Override
    public String getName() {
        return "firstJobListener";
    }

    @Override
    public void jobToBeExecuted(JobExecutionContext context) {
        System.out.println(getName() + "-jobToBeExecuted....");
    }

    @Override
    public void jobExecutionVetoed(JobExecutionContext context) {
        System.out.println(getName() + "-jobExecutionVetoed....");

    }

    @Override
    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
        System.out.println(getName() + "-jobWasExecuted....");
    }
}

2.2 继承JobListenerSupport

其实和实现jobListener接口无差异, getName()是必须重写的方法.

public class MySecondJobListener extends JobListenerSupport {
    @Override
    public String getName() {
        return "secondJobListener";
    }

    @Override
    public void jobToBeExecuted(JobExecutionContext context) {
        System.out.println(getName() + "-jobToBeExecuted....");
    }

    @Override
    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
        System.out.println(getName() + "-jobWasExecuted....");
    }
}

2.3 测试用例

笔者推荐在调度器启动之前添加任务监听器.

public class Test07 extends BaseQuartzJdbcTest{

    // 测试job监听器
    @Test
    public void test_jobListener() throws SchedulerException {

        // 添加scheduler 监听器
        scheduler.getListenerManager().addSchedulerListener(new MyScheduerListener());

        // 3. 创建定时任务
        JobDetail job = JobBuilder.newJob(ListenerJob.class)
                .withIdentity("listenerJob", "jobGroup7")
                .requestRecovery(true)
                .build();


        // 4. 创建简单触发器
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("jobListenerTrigger", "triggerGroup7")
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        .withRepeatCount(0))
                .build();

        // 5. 将定时任务添加到调度队列中
        scheduler.scheduleJob(job, trigger);


        // 6. 笔者推荐在调度器启动之前添加监听器
        // 自定义监听器匹配模式
        KeyMatcher<JobKey> jobKeyMatcher = KeyMatcher.keyEquals(JobKey.jobKey("listenerJob", "jobGroup7"));
        // 依次添加监听器1和监听器2
        scheduler.getListenerManager().addJobListener(new MyFirstJobListener(), jobKeyMatcher);
        scheduler.getListenerManager().addJobListener(new MySecondJobListener(), jobKeyMatcher);

        // 7. 启动调度器
        scheduler.start();

    }

    // 重新启动之后, 并无监听. 说明quartz并不会持久化监听器
    @Test
    public void start() throws SchedulerException {
        this.scheduler.start();

    }
}

2.4 测试输出

从输出结果来看, 可以发现执行步骤:

  1. 执行监听器1 的jobToBeExecuted方法
  2. 执行监听器2 的jobToBeExecuted方法
  3. 执行定时任务的方法
  4. 执行监听器2的jobWasExecuted的方法
  5. 执行监听器1的jobWasExecuted的方法
firstJobListener-jobToBeExecuted....
secondJobListener-jobToBeExecuted....
org.zongf.learn.quartz.l01.job.ListenerJob- do job...
firstJobListener-jobWasExecuted....
secondJobListener-jobWasExecuted....
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!