Trigger最经常使用的有两种SimpleTrigger和CronTrigger,首先介绍Trigger的一些基础的信息,而后会详细描述这两种Trigger。ide
quartz中全部的触发器Trigger都有一些共有属性,如TriggerKey,startTime等,这些属性可使用TriggerBuilder进行设置。经常使用的属性举例以下:ui
(1) triggerKey:触发器的标识,由名称与分组惟一指定,便于调度器调用与查找。this
(2) jobKey: 当触发器被触发时,标识哪个任务Job应该被执行。spa
(3) startTime: 表示触发器第一次开始触发的时间。线程
(4) endTime: 表示触发器终止触发的时间。code
当存在多个触发器时,quartz可能没有足够的资源当即触发全部配置为同一时间触发的triggers,所以能够设置每一个Trigger的优先级。默认的优先级为5,可取任意的整型值,包括正数或负数。注意优先级仅用于全部相同时间触发的triggers。对象
Trigger未触发通常产生于调度器被关闭,或线程池不足时。不一样的Trigger类型有不一样的未启动指令。默认的,他们会使用"smart policy"指定。这些指令的使用场景在于,当scheduler开启时,它将搜索全部未启动的持久化的触发器,而后基于触发器各自配置"未启动指令"来更新触发器。未启动指令用于当trigger未正常触发时,是否恢复执行的场景。blog
与Trigger关联的Calendar对象,用于在指定的时间内不触发trigger,例如你有一个任务天天执行一次,但你不但愿在节假日执行时,Calendar此时派上用场。注意此Calendar为quartz自身的定义接口,而非Java自带的Calendar。接口
Calendar须要在Scheduler定义过程当中,经过scheduler.addCalendar()进行初始化和注册。ci
示例:
import static org.quartz.JobBuilder.*; import static org.quartz.TriggerBuilder.*; import static org.quartz.SimpleScheduleBuilder.*; Trigger t = newTrigger() .withIdentity("myTrigger") .forJob("myJob") .withSchedule(dailyAtHourAndMinute(9, 30)) // execute job daily at 9:30 .modifiedByCalendar("myHolidays") // but not on holidays .build(); // .. schedule job with trigger Trigger t2 = newTrigger() .withIdentity("myTrigger2") .forJob("myJob2") .withSchedule(dailyAtHourAndMinute(11, 30)) // execute job daily at 11:30 .modifiedByCalendar("myHolidays") // but not on holidays .build(); // .. schedule job with trigger2
当须要在规定时间执行一次或在规定的时间段以必定的时间间隔重复触发执行Job时,SimpleTrigger就能够知足。
SimpleTrigger的属性有:开始时间、结束时间、重复次数和重复的时间间隔。重复次数属性的值能够为0、正整数、或常量 SimpleTrigger.REPEAT_INDEFINITELY,重复的时间间隔属性值必须为0或长整型的正整数,以毫秒做为时间单位,当重复的时间间隔为0时,意味着与Trigger同时触发执行。若是有指定结束时间属性值,则结束时间属性优先于重复次数属性,这样的好处在于:当咱们须要建立一个每间隔10秒钟触发一次直到指定的结束时间的 Trigger,而无需去计算从开始到结束的所重复的次数,咱们只需简单的指定结束时间和使用REPEAT_INDEFINITELY做为重复次数的属性 值便可。
示例:
(1) 建立在特定时间触发,非重复的Trigger
import static org.quartz.TriggerBuilder.*; import static org.quartz.SimpleScheduleBuilder.*; import static org.quartz.DateBuilder.*: SimpleTrigger trigger = (SimpleTrigger) newTrigger() .withIdentity("trigger1", "group1") .startAt(myStartTime) // some Date .forJob("job1", "group1") // identify job with name, group strings .build();
(2) 建立在特定时间触发,重复间隔为10次,重复执行10次的Trigger
import static org.quartz.TriggerBuilder.*; import static org.quartz.SimpleScheduleBuilder.*; import static org.quartz.DateBuilder.*: trigger = newTrigger() .withIdentity("trigger3", "group1") .startAt(myTimeToStartFiring) // if a start time is not given (if this line were omitted), "now" is implied .withSchedule(simpleSchedule() .withIntervalInSeconds(10) .withRepeatCount(10)) // note that 10 repeats will give a total of 11 firings .forJob(myJob) // identify job with handle to its JobDetail itself .build();
(3) 建立5分钟后执行,且触发一次的Trigger
trigger = (SimpleTrigger) newTrigger() .withIdentity("trigger5", "group1") .startAt(futureDate(5, IntervalUnit.MINUTE)) // use DateBuilder to create a date in the future .forJob(myJobKey) // identify job with its JobKey .build();
(4) 建立当即执行,且重复间隔为5分钟,到22点结束的Trigger
trigger = newTrigger() .withIdentity("trigger7", "group1") .withSchedule(simpleSchedule() .withIntervalInMinutes(5) .repeatForever()) .endAt(dateOf(22, 0, 0)) .build();
(5) 建立在下一小时触发,且每2小时执行重复执行的Trigger
trigger = newTrigger() .withIdentity("trigger8") // because group is not specified, "trigger8" will be in the default group .startAt(evenHourDate(null)) // get the next even-hour (minutes and seconds zero ("00:00")) .withSchedule(simpleSchedule() .withIntervalInHours(2) .repeatForever()) // note that in this example, 'forJob(..)' is not called // - which is valid if the trigger is passed to the scheduler along with the job .build(); scheduler.scheduleJob(trigger, job);
SimpleTrigger的未启动指令包含以下:
MISFIRE_INSTRUCTION_SMART_POLICY
MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
MISFIRE_INSTRUCTION_FIRE_NOW
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT
构件SimpleTrigger的时候,能够指定Trigger的未启动指令:
trigger = newTrigger() .withIdentity("trigger7", "group1") .withSchedule(simpleSchedule() .withIntervalInMinutes(5) .repeatForever() .withMisfireHandlingInstructionNextWithExistingCount()) .build();
CronTrigger 支持比SimpleTrigger更具体、更复杂的调度。基于cron表达式,CronTrigger支持相似日历的重复间隔,而非单一的时间间隔。
序号 | 说明 | 是否必填 | 容许填写的值 | 容许的通配符 |
1 | 秒 | 是 | 0-59 | , - * / |
2 | 分 | 是 | 0-59 | , - * / |
3 | 小时 | 是 | 0-23 | , - * / |
4 | 日 | 是 | 1-31 | , - * ? / L W |
5 | 月 | 是 | 1-12或JAN-DEC | , - * / |
6 | 周 | 是 | 1-7或SUN-SAT | , - * ? / L # |
7 | 年 | 否 | 空或1999-2017 | , - * / |
通配符的说明:
(1) 反斜线(/)字符表示增量值。例如,在秒字段中“5/15”表明从第 5 秒开始,每 15 秒一次。
(2) 星号(*)字符是通配字符,表示该字段能够接受任何可能的值,例如:在分的字段上设置 "*",表示每一分钟都会触发。
(3) 问号(?)问号表示这个字段不包含具体值。若是指定月内日期,能够在月内日期字段中插入“?”,表示周内日期值可有可无。
(4) - 表示区间,例如 在小时上设置 "10-12",表示 10,11,12点都会触发。
(5) 逗号(, ) 表示指定多个值,例如在周字段上设置 "MON,WED,FRI" 表示周一,周三和周五触发。
(6) 井号(#)字符为给定月份指定具体的工做日实例。把“MON#2”放在周内日期字段中,表示把任务安排在当月的第二个星期一。
(7) L 表示最后的意思。在日字段设置上,表示当月的最后一天(依据当前月份,若是是二月还会依据是不是润年[leap]), 在周字段上表示星期六,至关于"7"或"SAT"。若是在"L"前加上数字,则表示该数据的最后一个。例如在周字段上设置"6L"这样的格式,则表示“本月最后一个星期五"。
(8) W 表示离指定日期的最近那个工做日(周一至周五). 例如在日字段上设置"15W",表示离每个月15号最近的那个工做日触发。若是15号正好是周六,则找最近的周五(14号)触发, 若是15号是周未,则找最近的下周一(16号)触发.若是15号正好在工做日(周一至周五),则就在该天触发。若是指定格式为 "1W",它则表示每个月1号日后最近的工做日触发。若是1号正是周六,则将在3号下周一触发。(注,"W"前只能设置具体的数字,不容许区间"-")。
注:'L'和 'W'能够组合使用。若是在日字段上设置"LW",则表示在本月的最后一个工做日触发。
cron表达式的举例以下:
0 10 * * * ?--------------每一个小时过10分执行一次 0 0/32 8,12 * * ? ----------天天8:32,12:32 执行一次 0 0/2 * * * ?--------------每2分钟执行一次 0 0 12 * * ?---------------在天天中午12:00触发 0 15 10 ? * *---------------天天上午10:15 触发 0 15 10 * * ?---------------天天上午10:15 触发 0 15 10 * * ? *---------------天天上午10:15 触发 0 15 10 * * ? 2005---------------在2005年中的天天上午10:15 触发 0 * 14 * * ?---------------天天在下午2:00至2:59之间每分钟触发一次 0 0/5 14 * * ?---------------天天在下午2:00至2:59之间每5分钟触发一次 0 0/5 14,18 * * ?---------------天天在下午2:00至2:59和6:00至6:59之间的每5分钟触发一次 0 0-5 14 * * ?---------------天天在下午2:00至2:05之间每分钟触发一次 0 10,44 14 ? 3 WED---------------每三月份的星期三在下午2:00和2:44时触发 0 15 10 ? * MON-FRI---------------从星期一至星期五的天天上午10:15触发 0 15 10 15 * ?---------------在每月的每15天的上午10:15触发 0 15 10 L * ?---------------在每月的最后一天的上午10:15触发 0 15 10 ? * 6L---------------在每月的最后一个星期五的上午10:15触发 0 15 10 ? * 6L 2002-2005---------------在2002, 2003, 2004 and 2005年的每月的最后一个星期五的上午10:15触发 0 15 10 ? * 6#3---------------在每月的第三个星期五的上午10:15触发 0 0 12 1/5 * ?---------------从每个月的第一天起每过5天的中午12:00时触发 0 11 11 11 11 ?---------------在每一个11月11日的上午11:11时触发
可使用TriggerBuilder 来定义CronTrigger对象。示例以下:
import static org.quartz.TriggerBuilder.*; import static org.quartz.CronScheduleBuilder.*; import static org.quartz.DateBuilder.*: trigger = newTrigger() .withIdentity("trigger3", "group1") .withSchedule(cronSchedule("0 0/2 8-17 * * ?")) .forJob("myJob", "group1") .build(); trigger = newTrigger() .withIdentity("trigger3", "group1") .withSchedule(dailyAtHourAndMinute(10, 42)) .forJob(myJobKey) .build(); trigger = newTrigger() .withIdentity("trigger3", "group1") .withSchedule(cronSchedule("0 42 10 * * ?")) .forJob(myJobKey) .build(); trigger = newTrigger() .withIdentity("trigger3", "group1") .withSchedule(weeklyOnDayAndHourAndMinute(DateBuilder.WEDNESDAY, 10, 42)) .forJob(myJobKey) .inTimeZone(TimeZone.getTimeZone("Asia/Shanghai")) .build(); trigger = newTrigger() .withIdentity("trigger3", "group1") .withSchedule(cronSchedule("0 42 10 ? * WED")) .inTimeZone(TimeZone.getTimeZone("Asia/Shanghai")) .forJob(myJobKey) .build();
CronTrigger的未启动指令包含:
MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
MISFIRE_INSTRUCTION_DO_NOTHING
MISFIRE_INSTRUCTION_FIRE_NOW
MISFIRE_INSTRUCTION_SMART_POLICY
未启动指令的使用:
trigger = newTrigger() .withIdentity("trigger3", "group1") .withSchedule(cronSchedule("0 0/2 8-17 * * ?") .withMisfireHandlingInstructionFireAndProceed()) .forJob("myJob", "group1") .build();