四. 为 CronTrigger 使用起迄日期
Cron 表达式是用来决定一个 Trigger 被触发执行一个 Job 的日期和次数。当你创建一个 CronTrigger 实例,假如没为它指定一个开始时间,这个 Trigger 当然就会假定是在依赖于 Cron 表达式尽早的被触发。例如,如果你用这个表达式
0 * 14-20 * * ?
这个 Trigger 会在每天的从下午 2 点到下午的 7:59 间的每分钟触发一次。一旦你运行了这个表达式的 CronTrigger,假如当前是下午 2 点后(不能超过 7:59 PM--译者注),它将会立即触发。它会在每天无限期的被触发。
另一方面,倘若你希望这个计划直到下一天才开始,并且只执行两天,你就可以用 CronTrigger 的 setStartTime() 和 setEndTime() 方法来形成一个 "定时箱" 来触发。代码 5.2 描述了限定 CronTrigger 仅触发两天的例子。
代码 5.2. 你可以对 CronTrigger 用 startTime 和 endTime
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 |
public class Listing_5_2 { static Log logger = LogFactory.getLog(Listing_5_2.class); public static void main(String[] args) { Listing_5_2 example = new Listing_5_2(); example.runScheduler(); } public void runScheduler() { Scheduler scheduler = null; try { // Create a default instance of the Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.start(); logger.info("Scheduler was started at " + new Date()); // Create the JobDetail JobDetail jobDetail = new JobDetail("PrintInfoJob", Scheduler.DEFAULT_GROUP, PrintInfoJob.class); // Create a CronTrigger try { // cron that fires every min from 2 8pm CronTrigger trigger = new CronTrigger("MyTrigger", null, "0 * 14-20 * * ?"); Calendar cal = Calendar.getInstance(); // Set the date to 1 day from now cal.add(Calendar.DATE, 1); trigger.setStartTime(cal.getTime()); // Move ahead 2 days to set the end time cal.add(Calendar.DATE, 2); trigger.setEndTime(cal.getTime()); scheduler.scheduleJob(jobDetail, trigger); } catch (ParseException ex) { logger.error("Couldn't parse cron expr", ex); } } catch (SchedulerException ex) { logger.error(ex); } } } |
代码 5.2 中的例子使用了 java.util.Calendar 来为 Trigger 选择一个开始和结束时间周期。在上面例子中,Trigger 将会在 Scheduler 启动后的下一天开始触发,并只在开始触发后的两天内有效。
使用 CronTrigger 的 startTime 和 endTime 属性的效果有点像 SimpleTrigger。
五. 为 CronTrigger 使用 TriggerUtils
在第四章,"安排 Job" 中介绍了 org.quartz 包中的 TriggerUtils 类,它简化了两种类型的 Trigger 的创建。只要可能的话,你应该尝试用 TriggerUtils 类的方法来创建你的 Trigger。
例如,假如你需要在每天的下午 5:30 执行一个 Job,你可以用下面的代码:
1 2 3 4 5 6 7 |
try { // A CronTrigger that fires @ 5:30PM CronTrigger trigger = new CronTrigger("CronTrigger", null, "0 30 17 ? * *"); } catch (ParseException ex) { logger.error("Couldn't parse cron expression", ex); } |
或者你能用上 TriggerUtils,如下:
1 2 3 |
// A CronTrigger that fires @ 5:30PM Trigger trigger = TriggerUtils.makeDailyTrigger(17, 30); trigger.setName("CronTrigger"); |
TriggerUtils 使得我们更简单方便的使用 Trigger,而又未放弃太多的灵活性。
六. 在 JobInitializationPlugin 中使用 CronTrigger
尽管我们要到第八章,"使用 Quartz 插件" 才会讲到插件,但还是值得提前展现一下 CronTrigger 如何应用于 quartz_jobs.xml 文件中来指定 Job 信息的。JobInitialzationPlugin 可用来从 XML 文件中加载 Job 的信息。
正如 SimpleTrigger 一样,你可在 XML 文件中指定 CronTrigger 的表达式,并且 Quartz 的 Scheduler 将会利用这一信息来安排你的 Job。这对于你想在你的程序代码之外声明你的 Job 信息时特别方便。代码 5.3 显示了 quartz_jobs.xml 文件内容,它被 JobInitializationPlugin 用来加作 Job 信息。
代码 5.3. CronTrigger 可在 XML 文件中指定,并由 JobInitializationPlugin 加载
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 |
<?xml version='1.0' encoding='utf-8'?> <quartz> <job> <job-detail> <name>PrintInfoJob</name> <group>DEFAULT</group> <description> A job that prints out some basic information. </description> <job-class> org.cavaness.quartzbook.common.PrintInfoJob </job-class> </job-detail> <trigger> <cron> <name>printJobInfoTrigger</name> <group>DEFAULT</group> <job-name>PrintInfoJob</job-name> <job-group>DEFAULT</job-group> <!-- Fire 7:30am Monday through Friday --> <cron-expression>0 30 7 ? * MON-FRI</cron-expression> </cron> </trigger> </job> </quartz> |
代码 5.3 中的 Cron 表达式与 代码 5.1 中。当 Quartz 加载这个 XML 后,就会安排 PrintInfoJob (也已在 XML 中列出) 在从星期一到星期五的早上 7:30 执行。关于 JobInitializationPlugin 更多的说明见第八章。
本文链接 https://yanbin.blog/quartz-job-scheduling-framework-5-3/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
谢谢你,上次帮我解决一个问题。
1、如果我是在spring里面配置使用quartz,那我该怎么设置setStartTime和endTime。
2、假如我只想在不是节假日的时间内触发,像4月4日是清明节,国家规定放假,不做触发。当然我有一个表专门保存节假日。像这些动态的时间(每年的节假日国家规定可能不一样)我怎么和spring配置在一起使用呢?
再次感谢你的好文章。
@nesta 看 Quartz Job Scheduling Framework[翻译]第四章. 部署 Job (第四部分) http://www.blogjava.net/Unmi/archive/2008/01/08/173066.html Quartz 还提供了一个 org.quartz.Calender 接口,可以用它来排除某些节假日,如下面的代码可让 job 在 7 月 4 日 不执行,exclude // Create an instance of the Quartz AnnualCalendar AnnualCalendar cal = new AnnualCalendar(); // exclude July 4th Calendar gCal = GregorianCalendar.getInstance(); gCal.set(Calendar.MONTH, Calendar.JULY); gCal.set(Calendar.DATE, 4); cal.setDayExcluded(gCal, true); // Add to scheduler, replace existing, update triggers scheduler. addCalendar("bankHolidays", cal, true, true); /* * Set up a trigger to start firing now, repeat forever * and have (60000 ms) between each firing. */ Trigger trigger = TriggerUtils.makeImmediateTrigger("myTrigger", -1,60000); // Trigger will use Calendar to exclude firing times trigger.setCalendarName("bankHolidays"); 至于 spring 中如何配置,要看看… Read more »
谢谢,我研究一把
@叶黄莺:
最近又遇到一个问题,为什么运行了一段时间后,不能触发了。。大概会是什么原因引起的呢?程序中没有报错。
quartz.properties 中关于工作线程数量的设置设大一些,默认为10个
我一共配置了三个触发的,一个是每隔10秒执行一次,一个是每隔10分钟执行,一个是每隔3小时执行一次。是不是因为线程数少的原因呢?
另外配置quartz.properties这个文件,是不是把quartz.jar包中的文件
org.quartz.threadPool.threadCount = 10
改为
org.quartz.threadPool.threadCount = 20
然后把这个文件放在WEB-INF\classes目录下就可以了???
quartz.jar会把这个文件替换他原来默认的quartz.properties ?
是的,试一试看看吧。
隔叶黄莺您好!
感谢您的心情工作,给大家提供了这么多文档。
能不能吧这些文档的word半发给我一份吗? 十分感激!!
我的邮箱是 zhang.xiaoming@neusoft.com
不知能否把你已翻译的文档发份给我呢,万分感谢,我的邮箱是jamesyueyb@163.com
初步的所有翻译文稿已汇集成一个 chm 文件,过几日我将发布在这里,提供 下载,与大家一同分享。