Quartz使用(4) - Quartz監聽器Listerner


1. 概述

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

2. JobListener

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

public interface JobListener {

    public String getName();

    public void jobToBeExecuted(JobExecutionContext context);

    public void jobExecutionVetoed(JobExecutionContext context);

    public void jobWasExecuted(JobExecutionContext context,
            JobExecutionException jobException);

}
View Code

 其中:

1) getName方法:用於獲取該JobListener的名稱。

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

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

4) jobWasExecuted方法:Scheduler在JobDetail被執行之后調用這個方法

示例:

下面的代碼展示了簡單使用JobListener的使用,其中區別了全局監聽器與非全局監聽器的創建及使用方法。

1) 簡單的HelloWordJob創建

package org.ws.quartz.test3;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorldJob implements Job{
    
    private static Logger logger = LoggerFactory.getLogger(HelloWorldJob.class);
    
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        logger.info("Hello World");
    }
}
View Code

2) 創建簡單的JobListener

package org.ws.quartz.test3;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SimpleJobListener implements JobListener{

    private static Logger logger = LoggerFactory.getLogger(SimpleJobListener.class);
    
    @Override
    public String getName() {
        String name = getClass().getSimpleName();
        logger.info(" listener name is:"+name);
        return name;
    }

    @Override
    public void jobToBeExecuted(JobExecutionContext context) {
        String jobName = context.getJobDetail().getKey().getName();
        logger.info(jobName + " is going to be executed");
    }

    @Override
    public void jobExecutionVetoed(JobExecutionContext context) {
        String jobName = context.getJobDetail().getKey().getName();
        logger.info(jobName + " was vetoed and not executed");
    }

    @Override
    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
        String jobName = context.getJobDetail().getKey().getName();
        logger.info(jobName + " was executed");

    }
}
View Code

3) 調度器的創建與執行

package org.ws.quartz.test3;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.EverythingMatcher;
import org.quartz.impl.matchers.KeyMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SimpleQuartzExample {
    
    private static Logger logger = LoggerFactory.getLogger(SimpleQuartzExample.class);
    
    public static void main(String[] args) throws SchedulerException, InterruptedException {
        
        SimpleQuartzExample exam = new SimpleQuartzExample();
        
        logger.info("init scheduler componets");
        
        // 創建調度器
        Scheduler scheduler = exam.createScheduler();
        
        // 創建兩個任務及對應的觸發器
        JobDetail jobDetail1 = exam.createJobDetail("HelloWord1_Job", "HelloWorld1_Group");
        Trigger trigger1 = exam.createTrigger("HelloWord1_Job", "HelloWorld1_Group");
        
        JobDetail jobDetail2 = exam.createJobDetail("HelloWord2_Job", "HelloWorld2_Group");
        Trigger trigger2 = exam.createTrigger("HelloWord2_Job", "HelloWorld2_Group");
        
        // 構建調度任務
        scheduler.scheduleJob(jobDetail1, trigger1);
        scheduler.scheduleJob(jobDetail2, trigger2);
        
        // 創建並注冊一個全局的Job Listener
        scheduler.getListenerManager().addJobListener(new SimpleJobListener(), EverythingMatcher.allJobs());
        
        // 創建並注冊一個指定任務的Job Listener
//        scheduler.getListenerManager().addJobListener(new SimpleJobListener(), KeyMatcher.keyEquals(JobKey.jobKey("HelloWorld1_Job", "HelloWorld1_Group")));
        
        logger.info("execute scheduler");
        // 開啟調度器
        scheduler.start();
        
        Thread.sleep(20000);
        
        scheduler.shutdown();
        
        logger.info("shut down scheduler");
    }

    protected Scheduler createScheduler() throws SchedulerException{
        return StdSchedulerFactory.getDefaultScheduler(); 
    }
    
    protected JobDetail createJobDetail(String jobName, String jobGroup){
        return JobBuilder.newJob(HelloWorldJob.class)
                .withIdentity(jobName, jobGroup)
                .build();
    }
    
    protected Trigger createTrigger(String triggerName, String triggerGroup){
        return  TriggerBuilder.newTrigger()
                .withIdentity(triggerName, triggerGroup)
                .withSchedule(
                        SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInSeconds(10)
                        .repeatForever()
                        ).build();
    }
}
View Code

① 執行全局監聽器的結果如下:

2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] init scheduler componets
  2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] execute scheduler
  2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job is going to be executed
  2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.HelloWorldJob1] Hello World
  2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job was executed
  2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord2_Job is going to be executed
  2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.HelloWorldJob1] Hello World
  2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:14:11 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord2_Job was executed
  2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job is going to be executed
  2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.HelloWorldJob1] Hello World
  2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job was executed
  2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord2_Job is going to be executed
  2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.HelloWorldJob1] Hello World
  2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:14:21 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord2_Job was executed
View Code

② 將代碼中的注釋去掉,並注釋全區監聽器的創建,執行非全局監聽器結果如下:

2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] init scheduler componets
  2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] execute scheduler
  2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
  2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job is going to be executed
  2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
  2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:32:57 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job was executed
  2017-07-16 17:33:07 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:33:07 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job is going to be executed
  2017-07-16 17:33:07 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
  2017-07-16 17:33:07 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:33:07 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job was executed
  2017-07-16 17:33:07 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:33:07 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
  2017-07-16 17:33:07 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job is going to be executed
  2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
  2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.SimpleJobListener] HelloWord1_Job was executed
  2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
  2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.SimpleJobListener]  listener name is:SimpleJobListener
  2017-07-16 17:33:17 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] shut down scheduler
  
View Code

備注:

除了代碼中將對應的job注冊到監聽器中的兩種方法,也有如下幾種其他方法:

1) 將同一任務組的任務注冊到監聽器中

scheduler.getListenerManager().addJobListener(new SimpleJobListener(), GroupMatcher.jobGroupEquals("HelloWorld2_Group"));
View Code

2) 將兩個任務組的任務注冊到監聽器中

scheduler.getListenerManager().addJobListener(new SimpleJobListener(), OrMatcher.or(GroupMatcher.jobGroupEquals("HelloWorld1_Group"), GroupMatcher.jobGroupEquals("HelloWorld2_Group")));
View Code

3. 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);
}
View Code

其中:

1) getName方法:用於獲取觸發器的名稱

2) triggerFired方法:當與監聽器相關聯的Trigger被觸發,Job上的execute()方法將被執行時,Scheduler就調用該方法。

3) vetoJobExecution方法:在 Trigger 觸發后,Job 將要被執行時由 Scheduler 調用這個方法。TriggerListener 給了一個選擇去否決 Job 的執行。假如這個方法返回 true,這個 Job 將不會為此次 Trigger 觸發而得到執行。

4) triggerMisfired方法:Scheduler 調用這個方法是在 Trigger 錯過觸發時。你應該關注此方法中持續時間長的邏輯:在出現許多錯過觸發的 Trigger 時,長邏輯會導致骨牌效應。你應當保持這上方法盡量的小。

5) triggerComplete方法:Trigger 被觸發並且完成了 Job 的執行時,Scheduler 調用這個方法。

 示例:

下面的例子簡單展示了TriggerListener的使用,其中創建並注冊TriggerListener與JobListener幾乎類似。

1) HelloWorldJob類

package org.ws.quartz.test3;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorldJob implements Job{
    
    private static Logger logger = LoggerFactory.getLogger(HelloWorldJob.class);
    
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        logger.info("Hello World");
    }
}
View Code

2) SimpleTriggerListener

package org.ws.quartz.test3;

import org.quartz.JobExecutionContext;
import org.quartz.Trigger;
import org.quartz.Trigger.CompletedExecutionInstruction;
import org.quartz.TriggerListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SimpleTriggerListener implements TriggerListener{
    
    private static Logger logger = LoggerFactory.getLogger(SimpleTriggerListener.class);
    
    private String name;
    
    public SimpleTriggerListener(String name) {
        this.name = name;
    }
    
    @Override
    public String getName() {
        return name;
    }

    @Override
    public void triggerFired(Trigger trigger, JobExecutionContext context) {
        String triggerName = trigger.getKey().getName();
        logger.info(triggerName + " was fired");
    }

    @Override
    public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
        String triggerName = trigger.getKey().getName();
        logger.info(triggerName + " was not vetoed");
        return false;
    }

    @Override
    public void triggerMisfired(Trigger trigger) {
        String triggerName = trigger.getKey().getName();
        logger.info(triggerName + " misfired");
    }

    @Override
    public void triggerComplete(Trigger trigger, JobExecutionContext context,
            CompletedExecutionInstruction triggerInstructionCode) {
        String triggerName = trigger.getKey().getName();
        logger.info(triggerName + " is complete");
    }
}
View Code

3) 任務調度與運行,涉及到多種TriggerListener的創建與注冊。

package org.ws.quartz.test3;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SimpleQuartzExample {
    
    private static Logger logger = LoggerFactory.getLogger(SimpleQuartzExample.class);
    
    public static void main(String[] args) throws SchedulerException, InterruptedException {
        
        SimpleQuartzExample exam = new SimpleQuartzExample();
        
        logger.info("init scheduler componets");
        
        // 創建調度器
        Scheduler scheduler = exam.createScheduler();
        
        // 創建兩個任務及對應的觸發器
        JobDetail jobDetail1 = exam.createJobDetail("HelloWord1_Job", "HelloWorld1_Group");
        Trigger trigger1 = exam.createTrigger("HelloWord1_Job", "HelloWorld1_Group");
        
        JobDetail jobDetail2 = exam.createJobDetail("HelloWord2_Job", "HelloWorld2_Group");
        Trigger trigger2 = exam.createTrigger("HelloWord2_Job", "HelloWorld2_Group");
        
        // 構建調度任務
        scheduler.scheduleJob(jobDetail1, trigger1);
        scheduler.scheduleJob(jobDetail2, trigger2);
        
        // 創建並注冊一個全局的Trigger Listener
        scheduler.getListenerManager().addTriggerListener(new SimpleTriggerListener("SimpleTrigger"), EverythingMatcher.allTriggers());
        
        // 創建並注冊一個局部的Trigger Listener
//        scheduler.getListenerManager().addTriggerListener(new SimpleTriggerListener("SimpleTrigger"), KeyMatcher.keyEquals(TriggerKey.triggerKey("HelloWord1_Job", "HelloWorld1_Group")));
        
        // 創建並注冊一個特定組的Trigger Listener
//        scheduler.getListenerManager().addTriggerListener(new SimpleTriggerListener("SimpleTrigger"), GroupMatcher.groupEquals("HelloWorld1_Group"));
        
        logger.info("execute scheduler");
        // 開啟調度器""
        scheduler.start();
        
        Thread.sleep(20000);
        
        scheduler.shutdown();
        
        logger.info("shut down scheduler");
    }

    protected Scheduler createScheduler() throws SchedulerException{
        return StdSchedulerFactory.getDefaultScheduler(); 
    }
    
    protected JobDetail createJobDetail(String jobName, String jobGroup){
        return JobBuilder.newJob(HelloWorldJob.class)
                .withIdentity(jobName, jobGroup)
                .build();
    }
    
    protected Trigger createTrigger(String triggerName, String triggerGroup){
        return  TriggerBuilder.newTrigger()
                .withIdentity(triggerName, triggerGroup)
                .withSchedule(
                        SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInSeconds(10)
                        .repeatForever()
                        ).build();
    }
}
View Code

執行全局監聽器的結果如下:

2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] init scheduler componets
  2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] execute scheduler
  2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job was fired
  2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job was not vetoed
  2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
  2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job is complete
  2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job was fired
  2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job was not vetoed
  2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
  2017-07-16 18:31:58 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job is complete
  2017-07-16 18:32:08 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job was fired
  2017-07-16 18:32:08 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job was not vetoed
  2017-07-16 18:32:08 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
  2017-07-16 18:32:08 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job is complete
  2017-07-16 18:32:08 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job was fired
  2017-07-16 18:32:08 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job was not vetoed
  2017-07-16 18:32:08 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
  2017-07-16 18:32:08 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job is complete
  2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job was fired
  2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job was not vetoed
  2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
  2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord1_Job is complete
  2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job was fired
  2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job was not vetoed
  2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
  2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.SimpleTriggerListener] HelloWord2_Job is complete
  2017-07-16 18:32:18 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] shut down scheduler
  
View Code

4. SchedulerListener

SchedulerListener會在Scheduler的生命周期中關鍵事件發生時被調用。與Scheduler有關的事件包括:增加一個job/trigger,刪除一個job/trigger,scheduler發生嚴重錯誤,關閉scheduler等。

SchedulerListener的接口如下:

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();
}
View Code

其中:

1) jobScheduled方法:用於部署JobDetail時調用

2) jobUnscheduled方法:用於卸載JobDetail時調用

3) triggerFinalized方法:當一個 Trigger 來到了再也不會觸發的狀態時調用這個方法。除非這個 Job 已設置成了持久性,否則它就會從 Scheduler 中移除。

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

5) triggersResumed方法:Scheduler 調用這個方法是發生成一個 Trigger 或 Trigger 組從暫停中恢復時。假如是 Trigger 組的話,假如是 Trigger 組的話,triggerName 參數將為 null。參數將為 null。
6) jobsPaused方法:當一個或一組 JobDetail 暫停時調用這個方法。
7) jobsResumed方法:當一個或一組 Job 從暫停上恢復時調用這個方法。假如是一個 Job 組,jobName 參數將為 null。
8) schedulerError方法:在 Scheduler 的正常運行期間產生一個嚴重錯誤時調用這個方法。
9) schedulerStarted方法:當Scheduler 開啟時,調用該方法
10) schedulerInStandbyMode方法: 當Scheduler處於StandBy模式時,調用該方法
11) schedulerShutdown方法:當Scheduler停止時,調用該方法
12) schedulingDataCleared方法:當Scheduler中的數據被清除時,調用該方法。

 示例:

下面的代碼簡單描述了如何使用SchedulerListener方法:

1) HelloWorldJob

package org.ws.quartz.test3;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorldJob implements Job{
    
    private static Logger logger = LoggerFactory.getLogger(HelloWorldJob.class);
    
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        logger.info("Hello World");
    }
}
View Code

2) 簡單的SchedulerListener

package org.ws.quartz.test3;

import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.SchedulerException;
import org.quartz.SchedulerListener;
import org.quartz.Trigger;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SimpleSchedulerListener implements SchedulerListener{

    private static Logger logger = LoggerFactory.getLogger(SimpleSchedulerListener.class);
    
    @Override
    public void jobScheduled(Trigger trigger) {
        String jobName = trigger.getJobKey().getName();
        logger.info(jobName + " has been scheduled");
    }

    @Override
    public void jobUnscheduled(TriggerKey triggerKey) {
        logger.info(triggerKey + " is being unscheduled");
    }

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

    @Override
    public void triggerPaused(TriggerKey triggerKey) {
        logger.info(triggerKey + " is being paused");
    }

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

    @Override
    public void triggerResumed(TriggerKey triggerKey) {
        logger.info(triggerKey + " is being resumed");
    }

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

    @Override
    public void jobAdded(JobDetail jobDetail) {
        logger.info(jobDetail.getKey()+" is added");
    }

    @Override
    public void jobDeleted(JobKey jobKey) {
        logger.info(jobKey+" is deleted");
    }

    @Override
    public void jobPaused(JobKey jobKey) {
        logger.info(jobKey+" is paused");
    }

    @Override
    public void jobsPaused(String jobGroup) {
        logger.info("job group "+jobGroup+" is paused");
    }

    @Override
    public void jobResumed(JobKey jobKey) {
        logger.info(jobKey+" is resumed");
    }

    @Override
    public void jobsResumed(String jobGroup) {
        logger.info("job group "+jobGroup+" is resumed");
    }

    @Override
    public void schedulerError(String msg, SchedulerException cause) {
        logger.error(msg, 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");
    }
}
View Code

3) 任務調度以及SchedulerListener的加載調用

package org.ws.quartz.test3;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SimpleQuartzExample {
    
    private static Logger logger = LoggerFactory.getLogger(SimpleQuartzExample.class);
    
    public static void main(String[] args) throws SchedulerException, InterruptedException {
        
        SimpleQuartzExample exam = new SimpleQuartzExample();
        
        logger.info("init scheduler componets");
        
        // 創建調度器
        Scheduler scheduler = exam.createScheduler();
        
        // 創建任務及對應的觸發器
        JobDetail jobDetail = exam.createJobDetail("HelloWord_Job", "HelloWorld_Group");
        Trigger trigger = exam.createTrigger("HelloWord_Job", "HelloWorld_Group");
        
        
        // 構建調度任務
        scheduler.scheduleJob(jobDetail, trigger);
        
        // 創建SchedulerListener
        scheduler.getListenerManager().addSchedulerListener(new SimpleSchedulerListener());
        
        // 移除對應的SchedulerListener
//        scheduler.getListenerManager().removeSchedulerListener(new SimpleSchedulerListener());
        
        logger.info("execute scheduler");
        // 開啟調度器""
        scheduler.start();
        
        Thread.sleep(20000);
        
        scheduler.shutdown();
        
        logger.info("shut down scheduler");
    }

    protected Scheduler createScheduler() throws SchedulerException{
        return StdSchedulerFactory.getDefaultScheduler(); 
    }
    
    protected JobDetail createJobDetail(String jobName, String jobGroup){
        return JobBuilder.newJob(HelloWorldJob.class)
                .withIdentity(jobName, jobGroup)
                .build();
    }
    
    protected Trigger createTrigger(String triggerName, String triggerGroup){
        return  TriggerBuilder.newTrigger()
                .withIdentity(triggerName, triggerGroup)
                .withSchedule(
                        SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInSeconds(10)
                        .repeatForever()
                        ).build();
    }
}
View Code

執行后的結果如下:

2017-07-16 19:13:59 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] init scheduler componets
  2017-07-16 19:14:00 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] execute scheduler
  2017-07-16 19:14:00 [INFO]-[org.ws.quartz.test3.SimpleSchedulerListener] scheduler is being started
  2017-07-16 19:14:00 [INFO]-[org.ws.quartz.test3.SimpleSchedulerListener] scheduler has been started
  2017-07-16 19:14:00 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
  2017-07-16 19:14:10 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
  2017-07-16 19:14:20 [INFO]-[org.ws.quartz.test3.HelloWorldJob] Hello World
  2017-07-16 19:14:20 [INFO]-[org.ws.quartz.test3.SimpleSchedulerListener] scheduler is in standby mode
  2017-07-16 19:14:20 [INFO]-[org.ws.quartz.test3.SimpleSchedulerListener] scheduler is being shutdown
  2017-07-16 19:14:20 [INFO]-[org.ws.quartz.test3.SimpleSchedulerListener] scheduler has been shutdown
  2017-07-16 19:14:20 [INFO]-[org.ws.quartz.test3.SimpleQuartzExample] shut down scheduler
  
View Code


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM