Quartz Job Scheduling Framework[翻译]第十二章. Quartz Cookbook (第三部分)

·替换已部署的 Job


Quartz 提供了对已部署 Job 进行修改的灵活性。它是通过允许用修改后的 JobDetail 替换已有的 JobDetail 来支持这一特性的。为展未这一例子,让我们更新代码 12.4 中的 CheckEmailJob 类。 代码 12.4 是硬编码了邮件属性值到 Job 类中的。更好的做法是传入那些属性,如此则可以随意的改变它们; 那让我们改动 CheckEmailJob 来做到这一点。代码 12.7 显示的是那个 Job 的更新后的版本。

代码 12.7. 更新后的允许传入属性的 CheckEmailJob
 1package org.cavaness.quartzbook.chapter12;
 2
 3import java.util.Properties;
 4
 5import javax.mail.Folder;
 6import javax.mail.Message;
 7import javax.mail.MessagingException;
 8import javax.mail.NoSuchProviderException;
 9import javax.mail.Session;
10import javax.mail.Store;
11import org.quartz.Job;
12import org.quartz.JobDataMap;
13import org.quartz.JobExecutionContext;
14import org.quartz.JobExecutionException;
15
16public class CheckEmailJob implements Job {
17  public static String HOST_KEY = "mailHost" ;
18  public static String USERNAME_KEY = "username";
19  public static String PASSWORD_KEY = "password";
20
21  String mailHost = "some.mail.host";
22  String username = "aUsername";
23  String password = "aPassword";
24
25  public CheckEmailJob() {
26    super();
27  }
28  public void execute(JobExecutionContext context) throws JobExecutionException {
29    loadMailProperties(context.getJobDetail().getJobDataMap());
30    checkMail();
31  }
32
33  protected void loadMailProperties(JobDataMap map) {
34    if (map.getString(HOST_KEY) != null) {
35      mailHost = map.getString(HOST_KEY);
36    }
37
38    if (map.getString(USERNAME_KEY) != null) {
39      username = map.getString(USERNAME_KEY);
40    }
41
42    if (map.getString(PASSWORD_KEY) != null) {
43      password = map.getString(PASSWORD_KEY);
44    }
45  }
46  protected void checkMail() {
47    // Get session
48    Session session = null;
49
50    try {
51      // Get system properties
52      Properties props = System.getProperties();
53
54      session = Session.getDefaultInstance(props, null);
55
56      // Get the store
57      Store store = session.getStore("pop3");
58      store.connect(mailHost, username, password);
59
60      // Get folder
61      Folder folder = store.getFolder("INBOX");
62      folder.open(Folder.READ_ONLY);
63
64      // Get directory
65      Message message[] = folder.getMessages();
66      int numOfMsgs = message.length;
67      if (numOfMsgs > 0) {
68        for (int i = 0, n = numOfMsgs; i < n; i++) {
69          System.out.println("(" + i + " of " + numOfMsgs + "): "
70              + message[i].getFrom()[0] + "\t"
71              + message[i].getSubject());
72        }
73      } else {
74        System.out.println("No Messages for user");
75      }
76
77      // Close connection
78      folder.close(false);
79      store.close();
80    } catch (NoSuchProviderException e) {
81      // TODO Auto-generated catch block
82      e.printStackTrace();
83    } catch (MessagingException e) {
84      // TODO Auto-generated catch block
85      e.printStackTrace();
86    }
87  }
88  public static void main(String[] args) {
89    CheckEmailJob job = new CheckEmailJob();
90    job.checkMail();
91  }
92}

代码 12.7 的 CheckEmailJob 与 12.4 中版本主要的不同是 loadMailProperties() 方法。这个方法在 Job 首先执行的时候被调用,并检查 JobDataMap 看邮件属性是否有设置在这个 Map 中。假如有就用已设值,如果没有的话就使用 Job 类中的默认值。

代码 12.8 展示了属性值是如何被设置到 JobDataMap 中并传递给 Job 的。这些代码也显示了你怎么样才能用修改后的 JobDetail 实例替换已有实例来改变 Job 的。

代码 12.8. 显示如何更新一个已部署 Job 的例子
 1package org.cavaness.quartzbook.chapter12;
 2
 3import org.apache.commons.logging.Log;
 4import org.apache.commons.logging.LogFactory;
 5import org.quartz.JobDetail;
 6import org.quartz.Scheduler;
 7import org.quartz.SchedulerException;
 8import org.quartz.Trigger;
 9import org.quartz.TriggerUtils;
10import org.quartz.impl.StdSchedulerFactory;
11 public class Listing_12_8 {
12  static Log logger = LogFactory.getLog(Listing_12_8.class);
13
14  public static void main(String[] args) {
15    Listing_12_8 example = new Listing_12_8();
16    example.runScheduler();
17  }
18
19  public void runScheduler() {
20    Scheduler scheduler = null;
21
22    try {
23      // Get a Scheduler instance from the Factory
24      scheduler = StdSchedulerFactory.getDefaultScheduler();
25
26      // Start the scheduler
27      scheduler.start();
28
29      // Create a JobDetail for the Job
30      JobDetail jobDetail = new JobDetail("CheckEmailJob",
31          Scheduler.DEFAULT_GROUP, CheckEmailJob.class);
32
33      // Set the properties used by the job
34      jobDetail.getJobDataMap().put(CheckEmailJob.HOST_KEY, "host1");
35      jobDetail.getJobDataMap().put(CheckEmailJob.USERNAME_KEY, "username");
36      jobDetail.getJobDataMap().put(CheckEmailJob.PASSWORD_KEY, "password");
37
38      // Create a trigger that fires at 11:30pm every day
39      Trigger trigger = TriggerUtils.makeDailyTrigger(23, 30);
40      trigger.setName("emailJobTrigger");
41
42      // Associate the trigger with the job in the scheduler
43      scheduler.scheduleJob(jobDetail, trigger);
44
45      // Update the Job with a different mail host
46      jobDetail.getJobDataMap().put(CheckEmailJob.HOST_KEY, "host2");
47      scheduler.addJob(jobDetail, true);
48
49    } catch (SchedulerException ex) {
50      // deal with any exceptions
51      logger.error(ex);
52    }
53  }
54}

代码 12.8 中内容显示了两件事。其一,它向你展示了如何能通过 JobDataMap 向 Job 类传递邮件属性。其二,它描绘了你如何能使用 addJob() 方法去更新一个已部署 Job 的 JobDetailaddJob() 方法有一个布尔型的参数,用来告诉 Scheduler 是否用将要传入的 JobDetail 替换已部署的 JobDetail。Job 名和组必须与 Scheduler 中相匹配,这样才能用新的替换掉旧的。典型的做法是,你的代码会获取到已存在的 Job,然后修改它的 JobDataMap 中的内容,最后重新保存即可。

·更新已存在的 Trigger

你或许也需要更新某个 Job 更新已存在的 Trigger。你能用另一个来替换某个 Trigger,只要它是应用于同一个 Job。你可以通过使用 Scheduler 的 reschedulerJob()  方法来替换某个已有的 Trigger。

Trigger newTrigger = // Create a new Trigger// Replace the old trigger with a new one
sched.rescheduleJob(jobName, Scheduler.DEFAULT_GROUP, newTrigger);


·列示出 Scheduler 中的所有 Job

假如你正为 Quartz 构造一个 GUI,你可能需要列出已注册到 Scheduler 的所有 Job。代码 12.9 呈现了这个需求的一个应用。

代码 12.9. 列示出 Scheduler 中的所有 Job 的例子
 1package org.cavaness.quartzbook.chapter12;
 2
 3import org.apache.commons.logging.Log;
 4import org.apache.commons.logging.LogFactory;
 5import org.quartz.JobDetail;
 6import org.quartz.Scheduler;
 7import org.quartz.SchedulerException;
 8import org.quartz.Trigger;
 9import org.quartz.TriggerUtils;
10import org.quartz.impl.StdSchedulerFactory;
11
12public class Listing_12_9 {
13  static Log logger = LogFactory.getLog(Listing_12_9.class);
14
15  public static void main(String[] args) {
16    Listing_12_9 example = new Listing_12_9();
17    example.runScheduler();
18  }
19
20  public void runScheduler() {
21    Scheduler scheduler = null;
22
23    try {
24      // Get a Scheduler instance from the Factory
25      scheduler = StdSchedulerFactory.getDefaultScheduler();
26
27      // Start the scheduler
28      scheduler.start();
29
30      // Create a JobDetail for the Job
31      JobDetail jobDetail = new JobDetail("CheckEmailJob",
32          Scheduler.DEFAULT_GROUP, CheckEmailJob.class);
33
34      // Create a trigger that fires at 11:30pm every day
35      Trigger trigger = TriggerUtils.makeDailyTrigger(23, 30);
36      trigger.setName("emailJobTrigger");
37
38      // Associate the trigger with the job in the scheduler
39      scheduler.scheduleJob(jobDetail, trigger);
40
41      String[] jobGroups = scheduler.getJobGroupNames();
42      int numOfJobGroups = jobGroups.length;
43
44      for (int i = 0; i < numOfJobGroups; i++) {
45        System.out.println("Group: "  + jobGroups[i]
46            + " contains the following jobs");
47
48        String[] jobsInGroup = scheduler.getJobNames(jobGroups[i]);
49        int numOfJobsInGroup = jobsInGroup.length;
50
51        for (int j = 0; j < numOfJobsInGroup; j++) {
52          System.out.println(" - "  + jobsInGroup[j]);
53
54        }
55      }
56
57    } catch (SchedulerException ex) {
58      // deal with any exceptions
59      logger.error(ex);
60    }
61  }
62}

代码 12.9 中只注册了一个 Job,就是代码 12.7 中的 CheckEmailJob,且演示了如何循环 JobGroups 并罗列出每一个 group 下的所有 Job。在 GUI 中,罗列的结果可以呈现在列表框中或者是下拉列表中。

·列示出 Scheduler 中的所有 Trigger

你也能用类似于代码 12.9 中的方式罗列出所有 Trigger 来。下面的代码看起来十分相似,只是替换为 Trigger 而已。

String[] triggerGroups = sched.getTriggerGroupNames();
int numOfTriggerGroups = triggerGroups.length;
for (i = 0; i < numOfTriggerGroups; i++) {
   System.out.println("Group: "
      + triggerGroups[i]
      + " contains the following triggers");   String[] triggersInGroup = sched.getTriggerNames(triggerGroups[i]);
   int numOfTriggersInGroup = triggersInGroup.length;
   for (j = 0; j < numOfTriggersInGroup; j++) {
      System.out.println("- " + triggersInGroup[j]);
   }
}



如果你需要罗列出单个 Job 的所有 Trigger,你可用 Scheduler 的 getTriggersOfJob() 方法。这个方法返回一个与此 Job 相关联的 Trigger[] 数组。 永久链接 https://yanbin.blog/quartz-job-scheduling-framework-12-3/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。