·替换已部署的 Job
Quartz 提供了对已部署 Job 进行修改的灵活性。它是通过允许用修改后的 JobDetail 替换已有的 JobDetail 来支持这一特性的。为展未这一例子,让我们更新代码 12.4 中的 CheckEmailJob 类。代码 12.4 是硬编码了邮件属性值到 Job 类中的。更好的做法是传入那些属性,如此则可以随意的改变它们;那让我们改动 CheckEmailJob 来做到这一点。代码 12.7 显示的是那个 Job 的更新后的版本。
代码 12.7. 更新后的允许传入属性的 CheckEmailJob
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
package org.cavaness.quartzbook.chapter12; import java.util.Properties; import javax.mail.Folder; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.NoSuchProviderException; import javax.mail.Session; import javax.mail.Store; import org.quartz.Job; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class CheckEmailJob implements Job { public static String HOST_KEY = "mailHost" ; public static String USERNAME_KEY = "username"; public static String PASSWORD_KEY = "password"; String mailHost = "some.mail.host"; String username = "aUsername"; String password = "aPassword"; public CheckEmailJob() { super(); } public void execute(JobExecutionContext context) throws JobExecutionException { loadMailProperties(context.getJobDetail().getJobDataMap()); checkMail(); } protected void loadMailProperties(JobDataMap map) { if (map.getString(HOST_KEY) != null) { mailHost = map.getString(HOST_KEY); } if (map.getString(USERNAME_KEY) != null) { username = map.getString(USERNAME_KEY); } if (map.getString(PASSWORD_KEY) != null) { password = map.getString(PASSWORD_KEY); } } protected void checkMail() { // Get session Session session = null; try { // Get system properties Properties props = System.getProperties(); session = Session.getDefaultInstance(props, null); // Get the store Store store = session.getStore("pop3"); store.connect(mailHost, username, password); // Get folder Folder folder = store.getFolder("INBOX"); folder.open(Folder.READ_ONLY); // Get directory Message message[] = folder.getMessages(); int numOfMsgs = message.length; if (numOfMsgs > 0) { for (int i = 0, n = numOfMsgs; i < n; i++) { System.out.println("(" + i + " of " + numOfMsgs + "): " + message[i].getFrom()[0] + "\t" + message[i].getSubject()); } } else { System.out.println("No Messages for user"); } // Close connection folder.close(false); store.close(); } catch (NoSuchProviderException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (MessagingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { CheckEmailJob job = new CheckEmailJob(); job.checkMail(); } } |
代码 12.7 的 CheckEmailJob 与 12.4 中版本主要的不同是 loadMailProperties() 方法。这个方法在 Job 首先执行的时候被调用,并检查 JobDataMap 看邮件属性是否有设置在这个 Map 中。假如有就用已设值,如果没有的话就使用 Job 类中的默认值。
代码 12.8 展示了属性值是如何被设置到 JobDataMap 中并传递给 Job 的。这些代码也显示了你怎么样才能用修改后的 JobDetail 实例替换已有实例来改变 Job 的。
代码 12.8. 显示如何更新一个已部署 Job 的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
package org.cavaness.quartzbook.chapter12; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.TriggerUtils; import org.quartz.impl.StdSchedulerFactory; public class Listing_12_8 { static Log logger = LogFactory.getLog(Listing_12_8.class); public static void main(String[] args) { Listing_12_8 example = new Listing_12_8(); example.runScheduler(); } public void runScheduler() { Scheduler scheduler = null; try { // Get a Scheduler instance from the Factory scheduler = StdSchedulerFactory.getDefaultScheduler(); // Start the scheduler scheduler.start(); // Create a JobDetail for the Job JobDetail jobDetail = new JobDetail("CheckEmailJob", Scheduler.DEFAULT_GROUP, CheckEmailJob.class); // Set the properties used by the job jobDetail.getJobDataMap().put(CheckEmailJob.HOST_KEY, "host1"); jobDetail.getJobDataMap().put(CheckEmailJob.USERNAME_KEY, "username"); jobDetail.getJobDataMap().put(CheckEmailJob.PASSWORD_KEY, "password"); // Create a trigger that fires at 11:30pm every day Trigger trigger = TriggerUtils.makeDailyTrigger(23, 30); trigger.setName("emailJobTrigger"); // Associate the trigger with the job in the scheduler scheduler.scheduleJob(jobDetail, trigger); // Update the Job with a different mail host jobDetail.getJobDataMap().put(CheckEmailJob.HOST_KEY, "host2"); scheduler.addJob(jobDetail, true); } catch (SchedulerException ex) { // deal with any exceptions logger.error(ex); } } } |
代码 12.8 中内容显示了两件事。其一,它向你展示了如何能通过 JobDataMap 向 Job 类传递邮件属性。其二,它描绘了你如何能使用 addJob() 方法去更新一个已部署 Job 的 JobDetail。addJob() 方法有一个布尔型的参数,用来告诉 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 的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
package org.cavaness.quartzbook.chapter12; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.TriggerUtils; import org.quartz.impl.StdSchedulerFactory; public class Listing_12_9 { static Log logger = LogFactory.getLog(Listing_12_9.class); public static void main(String[] args) { Listing_12_9 example = new Listing_12_9(); example.runScheduler(); } public void runScheduler() { Scheduler scheduler = null; try { // Get a Scheduler instance from the Factory scheduler = StdSchedulerFactory.getDefaultScheduler(); // Start the scheduler scheduler.start(); // Create a JobDetail for the Job JobDetail jobDetail = new JobDetail("CheckEmailJob", Scheduler.DEFAULT_GROUP, CheckEmailJob.class); // Create a trigger that fires at 11:30pm every day Trigger trigger = TriggerUtils.makeDailyTrigger(23, 30); trigger.setName("emailJobTrigger"); // Associate the trigger with the job in the scheduler scheduler.scheduleJob(jobDetail, trigger); String[] jobGroups = scheduler.getJobGroupNames(); int numOfJobGroups = jobGroups.length; for (int i = 0; i < numOfJobGroups; i++) { System.out.println("Group: " + jobGroups[i] + " contains the following jobs"); String[] jobsInGroup = scheduler.getJobNames(jobGroups[i]); int numOfJobsInGroup = jobsInGroup.length; for (int j = 0; j < numOfJobsInGroup; j++) { System.out.println(" - " + jobsInGroup[j]); } } } catch (SchedulerException ex) { // deal with any exceptions logger.error(ex); } } } |
代码 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 Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。