Lesson 6: CronTrigger

CronTrigger is often more useful than SimpleTrigger, if you need a job-firing schedule that recurs based on calendar-like notions, rather than on the exactly specified intervals of SimpleTrigger.

With CronTrigger, you can specify firing-schedules such as “every Friday at noon”, or “every weekday and 9:30 am”, or even “every 5 minutes between 9:00 am and 10:00 am on every Monday, Wednesday and Friday during January”.

Even so, like SimpleTrigger, CronTrigger has a startTime which specifies when the schedule is in force, and an (optional) endTime that specifies when the schedule should be discontinued.

CronTrigger 比SimpleTrigger 更加有用,通过CronTrigger 可以指定firing-schedules , 比如”每个周五的中午”、”每个工作日的上午9:30”、”一月的每周一、周三和周五上午9:00至10:00的每个5分钟”。

SimpleTrigger 一样,CronTrigger 可以通过startTime 指定什么时间schedule开始调度执行,可选的endTime 指定schedule什么时候应该停止。

Cron Expressions

Cron-Expressions are used to configure instances of CronTrigger. Cron-Expressions are strings that are actually made up of seven sub-expressions, that describe individual details of the schedule. These sub-expression are separated with white-space, and represent:

  1. Seconds
  2. Minutes
  3. Hours
  4. Day-of-Month
  5. Month
  6. Day-of-Week
  7. Year (optional field)

An example of a complete cron-expression is the string “0 0 12 ? * WED” - which means “every Wednesday at 12:00:00 pm”.

Individual sub-expressions can contain ranges and/or lists. For example, the day of week field in the previous (which reads “WED”) example could be replaced with “MON-FRI”, “MON,WED,FRI”, or even “MON-WED,SAT”.

Wild-cards (the ‘’ character) can be used to say “every” possible value of this field. Therefore the ‘’ character in the “Month” field of the previous example simply means “every month”. A ‘*’ in the Day-Of-Week field would therefore obviously mean “every day of the week”.

All of the fields have a set of valid values that can be specified. These values should be fairly obvious - such as the numbers 0 to 59 for seconds and minutes, and the values 0 to 23 for hours. Day-of-Month can be any value 1-31, but you need to be careful about how many days are in a given month! Months can be specified as values between 0 and 11, or by using the strings JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC. Days-of-Week can be specified as values between 1 and 7 (1 = Sunday) or by using the strings SUN, MON, TUE, WED, THU, FRI and SAT.

The ‘/’ character can be used to specify increments to values. For example, if you put ‘0/15’ in the Minutes field, it means ‘every 15th minute of the hour, starting at minute zero’. If you used ‘3/20’ in the Minutes field, it would mean ‘every 20th minute of the hour, starting at minute three’ - or in other words it is the same as specifying ‘3,23,43’ in the Minutes field. Note the subtlety that “/35” does *not mean “every 35 minutes” - it mean “every 35th minute of the hour, starting at minute zero” - or in other words the same as specifying ‘0,35’.

The ‘?’ character is allowed for the day-of-month and day-of-week fields. It is used to specify “no specific value”. This is useful when you need to specify something in one of the two fields, but not the other. See the examples below (and CronTrigger JavaDoc) for clarification.

The ‘L’ character is allowed for the day-of-month and day-of-week fields. This character is short-hand for “last”, but it has different meaning in each of the two fields. For example, the value “L” in the day-of-month field means “the last day of the month” - day 31 for January, day 28 for February on non-leap years. If used in the day-of-week field by itself, it simply means “7” or “SAT”. But if used in the day-of-week field after another value, it means “the last xxx day of the month” - for example “6L” or “FRIL” both mean “the last friday of the month”. You can also specify an offset from the last day of the month, such as “L-3” which would mean the third-to-last day of the calendar month. When using the ‘L’ option, it is important not to specify lists, or ranges of values, as you’ll get confusing/unexpected results.

The ‘W’ is used to specify the weekday (Monday-Friday) nearest the given day. As an example, if you were to specify “15W” as the value for the day-of-month field, the meaning is: “the nearest weekday to the 15th of the month”.

The ‘#’ is used to specify “the nth” XXX weekday of the month. For example, the value of “6#3” or “FRI#3” in the day-of-week field means “the third Friday of the month”.

Here are a few more examples of expressions and their meanings - you can find even more in the JavaDoc for org.quartz.CronExpression


Cron-Expressions 是用来配置CronTrigger实例的,Cron-Expressions是由7个子表达式组成的字符串,子表达式由空格分开,分别是:

  1. 秒(Seconds)
  2. 分(Minutes)
  3. 小时(Hours)
  4. 日(Day-of-Month)
  5. 月(Month)
  6. 周几(Day-of-Week)
  7. 年(Year, 可选字段)

比如0 0 12 ? * WED, 表示每周三的下午12点。 周几字段还可以是MON-FRIMON,WED,FRI,或者MON-WED,SAT。 这里的*可以表示成每个月,如果*周几字段上可以表示成每周的每一天。

字段名 允许的值 允许的特殊字符
0-59 , - * /
0-59 , - * /
小时 0-23 , - * /
1-31 , - * ? / L W C
0-11 or JAN-DEC , - * /
周几 1-7(1=Sunday) or SUN-SAT , - * ? / L C #
empty, 1970-2099 , - * /

“?”字符:表示没有特定的值,在”日”字段和”周几”字段中使用,在这两个字段中只能在其中一个字段上使用。

“,”字符:指定数个值

“-”字符:指定一个值的范围

“/”字符:用在指定一个值的增加幅度。n/m表示从n开始,每次增加m。 
比如在分的字段使用 “0/15”, 表示一个小时的每一个15分钟,从0分开始。继续在分字段使用使用”3/20”, 表示一个小时的每20分钟,从第3分开始(和使用”3,23,43”一样)。如果是”/35”就不是表示每35分钟了,表示从0开始,一小时的第35分钟,和指定”0,35”一样。

“L”字符:用在”日”字段和”周几”字段里,”日”字段表示一个月中的最后一天(比如1月的31号),用在”周几”字段表示该周最后一天周六(7或者SAT)。如果是”L”前有具体的内容, 那就具有其他的含义了,比如在”周几”字段中的”6L”或者”FRIL”都表示本月的最后一个星期五。还可以为L设置偏移值,如在”日”字段使用”L-3”,若现在是9月份,这里就表示9月的28号,提前了3天。注意:在使用“L”参数时,不要指定列表或范围,因为这会导致问题。

“W”字符:指定离 给定日期 最近的工作日(周一到周五),比如在”日”字段指定”15W”, 表示 离本月15号最近的工作日。

“#”字符:用在”周几”字段,表示该月第几个周X,6#3表示该月第3个周五。

“*”:代表所有可能值


Example Cron Expressions

CronTrigger Example 1 - an expression to create a trigger that simply fires every 5 minutes

“0 0/5 * * * ?”

CronTrigger Example 2 - an expression to create a trigger that fires every 5 minutes, at 10 seconds after the minute (i.e. 10:00:10 am, 10:05:10 am, etc.).

“10 0/5 * * * ?”

CronTrigger Example 3 - an expression to create a trigger that fires at 10:30, 11:30, 12:30, and 13:30, on every Wednesday and Friday.

“0 30 10-13 ? * WED,FRI”

CronTrigger Example 4 - an expression to create a trigger that fires every half hour between the hours of 8 am and 10 am on the 5th and 20th of every month. Note that the trigger will NOT fire at 10:00 am, just at 8:00, 8:30, 9:00 and 9:30

“0 0/30 8-9 5,20 * ?”

Note that some scheduling requirements are too complicated to express with a single trigger - such as “every 5 minutes between 9:00 am and 10:00 am, and every 20 minutes between 1:00 pm and 10:00 pm”. The solution in this scenario is to simply create two triggers, and register both of them to run the same job.

0 0/5 * * * ?: 每隔5分钟执行一次

0 5/15 0-23 * * *: 从5分开始,每15分钟执行一次,到了最后一次执行时间正好是23:50

10 0/5 * * * ?: 每5分钟执行一次,比如10:00:10 am, 10:05:10 am

0 30 10-13 ? * WED,FRI: 在周三和周五的10:30, 11:30, 12:30和13:30执行

0 0/30 8-9 5,20 * ?: 每个月的5号和20号的上午8点到9点每半小时执行一次

对于一些特殊的需求,比如上午的9点到10点每5分钟执行一次,然后下午的1点和10点每20分钟执行一次,这种情况下可以创建两个triggers,将这两个triggers注册到schedule中,去运行同一个job。

Building CronTriggers

CronTrigger instances are built using TriggerBuilder (for the trigger’s main properties) and CronScheduleBuilder (for the CronTrigger-specific properties). To use these builders in a DSL-style, use static imports:

CronTrigger实例可以通过TriggerBuilder(多数主要的属性都有)和CronScheduleBuilder(指定CronTrigger的属性)。可以导入其的静态方法:

import static org.quartz.TriggerBuilder.*;
import static org.quartz.CronScheduleBuilder.*;
import static org.quartz.DateBuilder.*:
Build a trigger that will fire every other minute, between 8am and 5pm, every day:

创建一个每天上午8点到下午17点每两分钟触发一次的trigger(17点以后、18点以前也会执行)
trigger = newTrigger()
    .withIdentity("trigger3", "group1")
    .withSchedule(cronSchedule("0 0/2 8-17 * * ?"))
    .forJob("myJob", "group1")
    .build();

Build a trigger that will fire daily at 10:42 am:

创建一个每天上午10:42执行的trigger

 trigger = newTrigger()
    .withIdentity("trigger3", "group1")
    .withSchedule(dailyAtHourAndMinute(10, 42))
    .forJob(myJobKey)
    .build();
or -

  trigger = newTrigger()
    .withIdentity("trigger3", "group1")
    .withSchedule(cronSchedule("0 42 10 * * ?"))
    .forJob(myJobKey)
    .build();
Build a trigger that will fire on Wednesdays at 10:42 am, in a TimeZone other than the system’s default:

创建一个在 周三上午10:42执行的trigger,使用系统默认的时区

 trigger = newTrigger()
    .withIdentity("trigger3", "group1")
    .withSchedule(weeklyOnDayAndHourAndMinute(DateBuilder.WEDNESDAY, 10, 42))
    .forJob(myJobKey)
    .inTimeZone(TimeZone.getTimeZone("America/Los_Angeles"))
    .build();
or
trigger = newTrigger()
    .withIdentity("trigger3", "group1")
    .withSchedule(cronSchedule("0 42 10 ? * WED"))
    .inTimeZone(TimeZone.getTimeZone("America/Los_Angeles"))
    .forJob(myJobKey)
    .build();


CronTrigger Misfire Instructions

The following instructions can be used to inform Quartz what it should do when a misfire occurs for CronTrigger. (Misfire situations were introduced in the More About Triggers section of this tutorial). These instructions are defined as constants on CronTrigger itself (including JavaDoc describing their behavior). The instructions include:

Misfire Instruction Constants of CronTrigger

下面的instructions可以用来通知quartz当misfire出现的时候应该做些什么,主要是针对CronTrigger的。下面的这些定义在CronTrigger中的instructions常量:


MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
MISFIRE_INSTRUCTION_DO_NOTHING
MISFIRE_INSTRUCTION_FIRE_NOW

All triggers also have the Trigger.MISFIRE_INSTRUCTION_SMART_POLICY instruction available for use, and this instruction is also the default for all trigger types. The ‘smart policy’ instruction is interpreted by CronTrigger as MISFIRE_INSTRUCTION_FIRE_NOW. The JavaDoc for the CronTrigger.updateAfterMisfire() method explains the exact details of this behavior.

When building CronTriggers, you specify the misfire instruction as part of the simple schedule (via CronSchedulerBuilder):

所有的trigger都默认有了Trigger.MISFIRE_INSTRUCTION_SMART_POLICY instruction, 
CronTrigger 将smart policy执行为MISFIRE_INSTRUCTION_FIRE_NOW,JavaDoc 对CronTrigger.updateAfterMisfire()的行为有详尽的解释。

创建CronTrigger,指定misfire instruction:


trigger = newTrigger()
    .withIdentity("trigger3", "group1")
    .withSchedule(cronSchedule("0 0/2 8-17 * * ?")
        ..withMisfireHandlingInstructionFireAndProceed())
    .forJob("myJob", "group1")
    .build();







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值