Quartz監聽器Listerner

概述

Quartz的監聽器用於當任務調度中你所關注事件發生時,可以及時獲取這一事件的通知。Quartz監聽器主要有JobListener、TriggerListener、SchedulerListener三種,顧名思義,分別表示任務、觸發器、調度器對應的監聽器。三者的使用方法相似,在開始介紹三種監聽器以前,須要明確兩個概念:全局監聽器與非全局監聽器,兩者的區別在於:全局監聽器可以接收到全部的Job/Trigger的事件通知,而非全局監聽器只能接收到在其上註冊的Job或Trigger的事件,不在其上註冊的Job或Trigger則不會進行監聽。java

JobListener

任務調度過程當中,與任務Job相關的事件包括:job開始要執行的提示; job執行完成的提示燈。其接口以下:apache

public interface JobListener {

    public String getName();

    public void jobToBeExecuted(JobExecutionContext context);

    public void jobExecutionVetoed(JobExecutionContext context);

    public void jobWasExecuted(JobExecutionContext context,
            JobExecutionException jobException);

}
  • getName方法:用於獲取該JobListener的名稱。ide

  • jobToBeExecuted方法:Scheduler在JobDetail將要被執行時調用這個方法。ui

  • jobExecutionVetoed方法:Scheduler在JobDetail即將被執行,但又被TriggerListerner否決時會調用該方法this

  • jobWasExecuted方法:Scheduler在JobDetail被執行以後調用這個方法code

參考以下代碼orm

package com;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;

/**
 * @program: hello
 * @description:
 * @author: lee
 * @create: 2019-01-17
 **/
public class JobListenerDemo implements JobListener {
    @Override
    public String getName() {

        String name=getClass().getSimpleName();

        return name;
    }

    @Override
    public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {
        String jobname=jobExecutionContext.getJobDetail().getKey().getName();
        System.out.println(jobname+"is going to be executed");
    }

    @Override
    public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {
        String jobname=jobExecutionContext.getJobDetail().getKey().getName();
        System.out.println(jobname+"was vetoed and not executed");
    }

    @Override
    public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {
        String jobname=jobExecutionContext.getJobDetail().getKey().getName();
        System.out.println(jobname+"was executed");
    }
}


package com;

import com.sun.org.apache.xpath.internal.SourceTree;
import org.quartz.*;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @program: hello
 * @description: 自定義Job
 * @author: lee
 * @create: 2019-01-13
 **/

public class PJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        Date date=new Date();
        SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString=dateFormat.format(date);
        System.out.println("正在運行job任務,運行時間是:"+dateString);
    }
}

package com;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.EverythingMatcher;
import org.quartz.impl.matchers.KeyMatcher;

import java.util.Date;

/**
 * @program: hello
 * @description: 任務調度入口
 * @author: lee
 * @create: 2019-01-13
 **/
public class PScheduller {
    public static void main(String[] args) throws SchedulerException {

        PScheduller exam = new PScheduller();
        Scheduler scheduler = exam.createScheduler();

        JobDetail jobDetail = exam.createJobDetail("jobid", "jobgroup");

        Trigger trigger = exam.createTrigger("tiggername", "triggergroup");


        JobDetail jobDetail2 = exam.createJobDetail("jobid2", "jobgroup2");

        Trigger trigger2 = exam.createTrigger("tiggername2", "triggergroup2");

        scheduler.scheduleJob(jobDetail, trigger);
        scheduler.scheduleJob(jobDetail2, trigger2);
        // 建立並註冊一個全局的Job Listener
        //scheduler.getListenerManager().addJobListener(new JobListenerDemo(), EverythingMatcher.allJobs());
        // 建立並註冊一個指定任務的Job Listener
        scheduler.getListenerManager().addJobListener(new JobListenerDemo(), KeyMatcher.keyEquals(JobKey.jobKey("jobid","jobgroup")));
        scheduler.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        scheduler.shutdown();
    }

    protected Scheduler createScheduler() throws SchedulerException {
        return StdSchedulerFactory.getDefaultScheduler();
    }

    protected Trigger createTrigger(String triggerName, String triggerGroup) {
        return TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroup)
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(4).repeatForever())
                .build();
    }

    protected JobDetail createJobDetail(String jobName, String jobGroup) {
        return JobBuilder.newJob(PJob.class)
                .withIdentity(jobName, jobGroup)
                .build();
    }
}

輸出結果 第一種狀況接口

jobidis going to be executed
jobid2is going to be executed
正在運行job任務,運行時間是:2019-01-21 20:29:31
正在運行job任務,運行時間是:2019-01-21 20:29:31
jobidwas executed
jobid2was executed

第二種狀況生命週期

jobidis going to be executed
正在運行job任務,運行時間是:2019-01-21 20:28:31
jobidwas executed
正在運行job任務,運行時間是:2019-01-21 20:28:31

將同一任務組的任務註冊到監聽器中事件

scheduler.getListenerManager().addJobListener(new JobListenerDemo(), GroupMatcher.jobGroupEquals("jobgroup2"));

將兩個任務組的任務註冊到監聽器中

scheduler.getListenerManager().addJobListener(new JobListenerDemo(), OrMatcher.or(GroupMatcher.jobGroupEquals("jobgroup"),
                GroupMatcher.jobGroupEquals("jobgroup2")));

TriggerListener

任務調度過程當中,與觸發器Trigger相關的事件包括:觸發器觸發、觸發器未正常觸發、觸發器完成等。TriggerListener的接口以下:

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 調用這個方法。

代碼以下

package com;

import org.quartz.JobExecutionContext;
import org.quartz.Trigger;
import org.quartz.TriggerListener;

/**
 * @program: hello
 * @description:
 * @author: lee
 * @create: 2019-01-21
 **/
public class TriggerListenerDemo implements TriggerListener {

    private String name;

    public TriggerListenerDemo(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void triggerFired(Trigger trigger, JobExecutionContext jobExecutionContext) {
        String name=trigger.getKey().getName();
        System.out.println("trigger name is "+name);
    }

    @Override
    public boolean vetoJobExecution(Trigger trigger, JobExecutionContext jobExecutionContext) {
        return false;
    }

    @Override
    public void triggerMisfired(Trigger trigger) {
        String name=trigger.getKey().getName();
        System.out.println("triggerMisfired is running "+name);

    }

    @Override
    public void triggerComplete(Trigger trigger, JobExecutionContext jobExecutionContext, Trigger.CompletedExecutionInstruction completedExecutionInstruction) {
        String name=trigger.getKey().getName();
        System.out.println("triggerComplete is running "+name);
    }
}

調度程序中須要加入

scheduler.getListenerManager().addTriggerListener(new TriggerListenerDemo("TriggerListenerDemo"),
                GroupMatcher.groupEquals("triggergroup"));

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(Trigger trigger);

    public void triggersPaused(String triggerName, String triggerGroup);

    public void triggersResumed(String triggerName, String triggerGroup);

    public void jobsPaused(String jobName, String jobGroup);

    public void jobsResumed(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 中移除。

  • triggersPaused方法:Scheduler 調用這個方法是發生在一個 Trigger 或 Trigger 組被暫停時。假如是 Trigger 組的話,triggerName 參數將爲 null。

  • triggersResumed方法:Scheduler 調用這個方法是發生成一個 Trigger 或 Trigger 組從暫停中恢復時。假如是 Trigger 組的話,假如是 Trigger 組的話,triggerName 參數將爲 null。參數將爲 null。

  • jobsPaused方法:當一個或一組 JobDetail 暫停時調用這個方法。

  • jobsResumed方法:當一個或一組 Job 從暫停上恢復時調用這個方法。假如是一個 Job 組,jobName 參數將爲 null。

  • schedulerError方法:在 Scheduler 的正常運行期間產生一個嚴重錯誤時調用這個方法。

  • schedulerStarted方法:當Scheduler 開啓時,調用該方法

  • schedulerInStandbyMode方法: 當Scheduler處於StandBy模式時,調用該方法

  • schedulerShutdown方法:當Scheduler中止時,調用該方法

  • schedulingDataCleared方法:當Scheduler中的數據被清除時,調用該方法。

示例:

package com;

import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @program: hello
 * @description:
 * @author: lee
 * @create: 2019-01-21
 **/
public class SchedullerListener implements SchedulerListener {

    private static Logger logger = LoggerFactory.getLogger(SchedullerListener.class);

    @Override
    public void jobScheduled(Trigger trigger) {
        String jobName = trigger.getJobKey().getName();
        System.out.println(jobName + " has been scheduled");
    }

    @Override
    public void jobUnscheduled(TriggerKey triggerKey) {

        System.out.println(triggerKey + " is being unscheduled");
    }

    @Override
    public void triggerFinalized(Trigger trigger) {
        System.out.println("Trigger is finished for " + trigger.getJobKey().getName());
    }

    @Override
    public void triggerPaused(TriggerKey triggerKey) {
        System.out.println(triggerKey + " is being paused");
    }

    @Override
    public void triggersPaused(String triggerGroup) {
        System.out.println("trigger group "+triggerGroup + " is being paused");
    }

    @Override
    public void triggerResumed(TriggerKey triggerKey) {
        System.out.println(triggerKey + " is being resumed");
    }

    @Override
    public void triggersResumed(String triggerGroup) {
        System.out.println("trigger group "+triggerGroup + " is being resumed");
    }

    @Override
    public void jobAdded(JobDetail jobDetail) {
        System.out.println(jobDetail.getKey()+" is added");
    }

    @Override
    public void jobDeleted(JobKey jobKey) {
        System.out.println(jobKey+" is deleted");
    }

    @Override
    public void jobPaused(JobKey jobKey) {
        System.out.println(jobKey+" is paused");
    }

    @Override
    public void jobsPaused(String jobGroup) {
        System.out.println("job group "+jobGroup+" is paused");
    }

    @Override
    public void jobResumed(JobKey jobKey) {
        System.out.println(jobKey+" is resumed");
    }

    @Override
    public void jobsResumed(String jobGroup) {
        System.out.println("job group "+jobGroup+" is resumed");

    }

    @Override
    public void schedulerError(String msg, SchedulerException cause) {
        System.out.println(cause.getUnderlyingException());
    }

    @Override
    public void schedulerInStandbyMode() {
        logger.info("scheduler is in standby mode");
    }

    @Override
    public void schedulerStarted() {
        logger.info("scheduler has been started");
    }

    @Override
    public void schedulerStarting() {
        logger.info("scheduler is being started");
    }

    @Override
    public void schedulerShutdown() {
        logger.info("scheduler has been shutdown");
    }

    @Override
    public void schedulerShuttingdown() {
        logger.info("scheduler is being shutdown");
    }

    @Override
    public void schedulingDataCleared() {
        logger.info("scheduler has cleared all data");
    }
}

調度器代碼

package com;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.EverythingMatcher;
import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.impl.matchers.KeyMatcher;
import org.quartz.impl.matchers.OrMatcher;

import java.util.Date;

/**
 * @program: hello
 * @description: 任務調度入口
 * @author: lee
 * @create: 2019-01-13
 **/
public class PScheduller {
    public static void main(String[] args) throws SchedulerException, InterruptedException {

        PScheduller exam = new PScheduller();
        Scheduler scheduler = exam.createScheduler();

        JobDetail jobDetail = exam.createJobDetail("jobid", "jobgroup");

        Trigger trigger = exam.createTrigger("tiggername", "triggergroup");



        scheduler.scheduleJob(jobDetail, trigger);

        // 建立SchedulerListener
        scheduler.getListenerManager().addSchedulerListener(new SchedullerListener());
        scheduler.start();

        Thread.sleep(20000);

        scheduler.shutdown();
    }

    protected Scheduler createScheduler() throws SchedulerException {
        return StdSchedulerFactory.getDefaultScheduler();
    }

    protected Trigger createTrigger(String triggerName, String triggerGroup) {
        return TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroup)
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(4).repeatForever())
                .build();
    }

    protected JobDetail createJobDetail(String jobName, String jobGroup) {
        return JobBuilder.newJob(PJob.class)
                .withIdentity(jobName, jobGroup)
                .build();
    }
}
相關文章
相關標籤/搜索