实现 Quartz监听 Job 事件

监听 Job 事件

org.quartz.JobListener 接口包含一系列的方法,它们会由 Job 在其生命周期中产生的某些关键事件时被调用。JobListener 可用的方法显示在代码 1 中。

代码 1. org.quartz.JobListener 接口中的方法

public interface JobListener {   
   public String getName();   
   public void jobToBeExecuted(JobExecutionContext context);   
   public void jobExecutionVetoed(JobExecutionContext context);   

   public void jobWasExecuted(JobExecutionContext context,   
           JobExecutionException jobException);   
}  
public interface JobListener {
   public String getName();
   public void jobToBeExecuted(JobExecutionContext context);
   public void jobExecutionVetoed(JobExecutionContext context);

   public void jobWasExecuted(JobExecutionContext context,
           JobExecutionException jobException);
}

JobListener 接口中的方法用途是十分明了的。然后,我们还是要对他们加以简单说明。

·getName() 方法

getName() 方法返回一个字符串用以说明 JobListener 的名称。对于注册为全局的监听器,getName() 主要用于记录日志,对于由特定 Job 引用的 JobListener,注册在 JobDetail 上的监听器名称必须匹配从监听器上 getName() 方法的返回值。在你看完一些例子之后就会很清楚了。

·jobToBeExecuted() 方法

Scheduler 在 JobDetail 将要被执行时调用这个方法。

·jobExecutionVetoed() 方法

Scheduler 在 JobDetail 即将被执行,但又被 TriggerListener 否决了时调用这个方法。

·jobWasExecuted() 方法

Scheduler 在 JobDetail 被执行之后调用这个方法。

代码 2 展示了一个很简单的 JobListener 实现。

代码 2. 一个简单的 JobListner 实现

package org.cavaness.quartzbook.chapter7;   

import org.apache.commons.logging.Log;   
import org.apache.commons.logging.LogFactory;   
import org.quartz.JobExecutionContext;   
import org.quartz.JobExecutionException;   
import org.quartz.JobListener;   

public class SimpleJobListener implements JobListener {   
     Log logger = LogFactory.getLog(SimpleJobListener.class);   

     public String getName() {   
          return getClass().getSimpleName();   
     }   

     public void jobToBeExecuted(JobExecutionContext context) {   
          String jobName = context.getJobDetail().getName();   
          logger.info(jobName + " is about to be executed");   
     }   
     public void jobExecutionVetoed(JobExecutionContext context) {   
          String jobName = context.getJobDetail().getName();   
          logger.info(jobName + " was vetoed and not executed()");   
     }   
     public void jobWasExecuted(JobExecutionContext context,   
               JobExecutionException jobException) {   

          String jobName = context.getJobDetail().getName();   
          logger.info(jobName + " was executed");   
     }   
}  
package org.cavaness.quartzbook.chapter7;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;

public class SimpleJobListener implements JobListener {
     Log logger = LogFactory.getLog(SimpleJobListener.class);

     public String getName() {
          return getClass().getSimpleName();
     }

     public void jobToBeExecuted(JobExecutionContext context) {
          String jobName = context.getJobDetail().getName();
          logger.info(jobName + " is about to be executed");
     }
     public void jobExecutionVetoed(JobExecutionContext context) {
          String jobName = context.getJobDetail().getName();
          logger.info(jobName + " was vetoed and not executed()");
     }
     public void jobWasExecuted(JobExecutionContext context,
               JobExecutionException jobException) {

          String jobName = context.getJobDetail().getName();
          logger.info(jobName + " was executed");
     }
}

代码 2 中的 JobListener 打印一个日志消息,很明显,只是监听器最基本的用法。你要实现的逻辑完全由你和你的应用需要而定。你也许想在 Job 成功完成后发送一个电子邮件,或者在 Job 被否决后部署另一个。你有在回调方法中执行几乎任何动作的自由。

前面,我们提到过 JobListener (和 TriggerListener) 能注册为全局或非全局的。注意了,我们并不需要事先知道在代码 2 中的 JobListener 是一个全局或是非全局的;我们仅仅是实现了接口和提供了监听器方法。代码 3 描绘了如何使用代码 2 中的 SimpleJobListner 使之注册为一个全局的 JobListener。

代码 3. 使用 SimpleJobListener 作为一个全局 JobListener

package org.cavaness.quartzbook.chapter7;   

import java.util.Date;   

import org.apache.commons.logging.Log;   
import org.apache.commons.logging.LogFactory;   
import org.cavaness.quartzbook.common.PrintInfoJob;   
import org.quartz.JobDetail;   
import org.quartz.JobListener;   
import org.quartz.Scheduler;   
import org.quartz.SchedulerException;   
import org.quartz.Trigger;   
import org.quartz.TriggerUtils;   
import org.quartz.impl.StdSchedulerFactory;   

public class Listing_7_3 {   
     static Log logger = LogFactory.getLog(Listing_7_3.class);   

     public static void main(String[] args) {   
          Listing_7_3 example = new Listing_7_3();   

          try {   
              example.startScheduler();   
          } catch (SchedulerException ex) {   
              logger.error(ex);   
          }   
     }   

     public void startScheduler() throws SchedulerException {   

          // Create an instance of the factory   
          Scheduler scheduler = null;   

          // Create the scheduler and JobDetail   
          scheduler = StdSchedulerFactory.getDefaultScheduler();   
          JobDetail jobDetail = new JobDetail("PrintInfoJob",   
                    Scheduler.DEFAULT_GROUP, PrintInfoJob.class);   

         /*  
          * Set up a trigger to start firing now, with no end  
          * date/time, repeat forever and have  
          * 10 secs (10000 ms) between each firing.  
          */  
         Trigger trigger = TriggerUtils.makeSecondlyTrigger(10);   
         trigger.setName("SimpleTrigger");   
         trigger.setStartTime(new Date());   

         // Register the JobDetail and Trigger   
         scheduler.scheduleJob(jobDetail, trigger);   

         // Create and register the global job listener   
         JobListener jobListener =   
              new SimpleJobListener("SimpleJobListener");   

         scheduler.addGlobalJobListener(jobListener);   
         // Start the scheduler   
         scheduler.start();   
         logger.info("Scheduler was started at " + new Date());   
    }   
}  
package org.cavaness.quartzbook.chapter7;

import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.cavaness.quartzbook.common.PrintInfoJob;
import org.quartz.JobDetail;
import org.quartz.JobListener;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;

public class Listing_7_3 {
     static Log logger = LogFactory.getLog(Listing_7_3.class);

     public static void main(String[] args) {
          Listing_7_3 example = new Listing_7_3();

          try {
              example.startScheduler();
          } catch (SchedulerException ex) {
              logger.error(ex);
          }
     }

     public void startScheduler() throws SchedulerException {

          // Create an instance of the factory
          Scheduler scheduler = null;

          // Create the scheduler and JobDetail
          scheduler = StdSchedulerFactory.getDefaultScheduler();
          JobDetail jobDetail = new JobDetail("PrintInfoJob",
                    Scheduler.DEFAULT_GROUP, PrintInfoJob.class);

         /*
          * Set up a trigger to start firing now, with no end
          * date/time, repeat forever and have
          * 10 secs (10000 ms) between each firing.
          */
         Trigger trigger = TriggerUtils.makeSecondlyTrigger(10);
         trigger.setName("SimpleTrigger");
         trigger.setStartTime(new Date());

         // Register the JobDetail and Trigger
         scheduler.scheduleJob(jobDetail, trigger);

         // Create and register the global job listener
         JobListener jobListener =
              new SimpleJobListener("SimpleJobListener");

         scheduler.addGlobalJobListener(jobListener);
         // Start the scheduler
         scheduler.start();
         logger.info("Scheduler was started at " + new Date());
    }
}

代码 3 中的代码现在看来是相当直截的。创建了一个 JobDetail 和 Trigger 并注册到了 Scheduler 实例上,这在前面我们已是做过许多次了。

代码 2 中的 SimpleJobListener 初始化后通过 Scheduler 调用 addGlobalJobListener() 方法注册为一个全局的 JobListener。最后,启动 Scheduler。

因为我们只配置了单个 Job (PrintInfoJob),我们获得回调也只是那个 JobDetail。不过,假如我们部署了其他 Job,我们也能看到第二个 Job 的回调日志信息,因为这个监听顺是配置为全局的。

·注册非全局的 JobListener

你还能使用代码 2 中的 SimpleJobListener 作为一个非全局的 JobListener。要做到这点,你仅需要修改代码 3 的 startScheduler() 方法中的代码。代码 4 显示了这一需要做的小小的改变。

代码 4. 使用 SimpleJobListener 作为非全局的 JobListener

package org.cavaness.quartzbook.chapter7;   

import java.util.Date;   

import org.apache.commons.logging.Log;   
import org.apache.commons.logging.LogFactory;   
import org.cavaness.quartzbook.common.PrintInfoJob;   
import org.quartz.JobDetail;   
import org.quartz.JobListener;   
import org.quartz.Scheduler;   
import org.quartz.SchedulerException;   
import org.quartz.Trigger;   
import org.quartz.TriggerUtils;   
import org.quartz.impl.StdSchedulerFactory;   

public class Listing_7_4 {   
     static Log logger = LogFactory.getLog(Listing_7_4.class);   

     public static void main(String[] args) {   
          Listing_7_4 example = new Listing_7_4();   

          try {   
               example.startScheduler();   
          } catch (SchedulerException ex) {   
               logger.error(ex);   
         }   
     }   

     public void startScheduler() throws SchedulerException {   

          Scheduler scheduler = null;   

          try {   
              // Create the scheduler and JobDetail   
              scheduler = StdSchedulerFactory.getDefaultScheduler();   
              JobDetail jobDetail =   
                        new JobDetail("PrintInfoJob",   
                        Scheduler.DEFAULT_GROUP,   
                        PrintInfoJob.class);   

              /*  
               * Set up a trigger to start firing now, with no end  
               * date/time, repeat forever and have  
               * 10 secs (10000 ms) between each firing.  
               */  
              Trigger trigger =   
                   TriggerUtils.makeSecondlyTrigger(10);   

              trigger.setName("SimpleTrigger");   
              trigger.setStartTime(new Date());   

              // Create the job listener   
              JobListener jobListener =   
                   new SimpleJobListener("SimpleJobListener");   

              // Register Listener as a nonglobal listener   
              scheduler.addJobListener(jobListener);   

              // Listener set on JobDetail before scheduleJob()   
                   jobDetail.addJobListener(jobListener.getName());   

              // Register the JobDetail and Trigger   
              scheduler.scheduleJob(jobDetail, trigger);   

              // Start the scheduler   
              scheduler.start();   
              logger.info("Scheduler started at " + new Date());   

         } catch (SchedulerException ex) {   
              logger.error(ex);   
         }   
    }   
}  
package org.cavaness.quartzbook.chapter7;

import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.cavaness.quartzbook.common.PrintInfoJob;
import org.quartz.JobDetail;
import org.quartz.JobListener;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;

public class Listing_7_4 {
     static Log logger = LogFactory.getLog(Listing_7_4.class);

     public static void main(String[] args) {
          Listing_7_4 example = new Listing_7_4();

          try {
               example.startScheduler();
          } catch (SchedulerException ex) {
               logger.error(ex);
         }
     }

     public void startScheduler() throws SchedulerException {

          Scheduler scheduler = null;

          try {
              // Create the scheduler and JobDetail
              scheduler = StdSchedulerFactory.getDefaultScheduler();
              JobDetail jobDetail =
                        new JobDetail("PrintInfoJob",
                        Scheduler.DEFAULT_GROUP,
                        PrintInfoJob.class);

              /*
               * Set up a trigger to start firing now, with no end
               * date/time, repeat forever and have
               * 10 secs (10000 ms) between each firing.
               */
              Trigger trigger =
                   TriggerUtils.makeSecondlyTrigger(10);

              trigger.setName("SimpleTrigger");
              trigger.setStartTime(new Date());

              // Create the job listener
              JobListener jobListener =
                   new SimpleJobListener("SimpleJobListener");

              // Register Listener as a nonglobal listener
              scheduler.addJobListener(jobListener);

              // Listener set on JobDetail before scheduleJob()
                   jobDetail.addJobListener(jobListener.getName());

              // Register the JobDetail and Trigger
              scheduler.scheduleJob(jobDetail, trigger);

              // Start the scheduler
              scheduler.start();
              logger.info("Scheduler started at " + new Date());

         } catch (SchedulerException ex) {
              logger.error(ex);
         }
    }
}

代码 4 很类似于代码 4 中的代码。因为 JobListener 是要注册为一个非全局的监听器,你就要调用 Scheduler 的 addJobListener() 方法而不是 addGlobalJobListener() 方法了。对于非全局的 JobListener,它应于任何引用到它的 JobDetail 使用 schedulerJob() 或 addJob() 方法注册之前被注册。

接下来,JobListener 的名字要设置给 JobDetail。注意,设置的不是 JobListener 实例,仅仅是它的名称。这是通过调用 addJobListener() 方法并传入名称来完成的。传递给 addJobListener() 方法的名称必须匹配从监听器的 getName() 方法返回的名称。如果 Scheduler 不能根据名称找到监听器,它会抛出一个 SchedulerException 异常。

最后,启动 Scheduler。

非全局 JobListener 相关步骤的顺序

加入一个非全局 JobListener 的步骤必须是依序完成。JobListener 必须首先加入到 Scheduler 中。接着,JobListener 才能够设置给 JobDetail 对象。之后,你就能使用 scheduleJob() 方法安全的把 JobDetail 加入到 Scheduler 中。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值