我们接着来学习Quartz的日历调度:
CronTrigger的作用:
基于 日历 的 作业调度器, 而不像 SimpleTrigger 那样精确指定间隔时间,比SimpleTrigger更常用;
应用于每个星期的星期几进行调度,每个月的几号进行调度..等,这种复杂调度;
Cron表达式 :
用于配置CronTrigger实例.
是由7个字表达式组成的字符串,描述了时间表的详细信息.
格式: [秒] [分] [时] [日] [月] [周] [年]
特殊字符意义对应表:
字段 | 是否必填 | 允许值 | 允许的特殊字符 |
---|---|---|---|
秒 | 是 | 0~59 | , - * / |
分 | 是 | 0~59 | , - * / |
时 | 是 | 0~23 | , - * / |
日 | 是 | 1~31 | , - * / ? L W |
月 | 是 | 1~12或JAN~DEC | , - * / |
周 | 是 | 1~7或SUN~SAT | , - * / ? L # |
年 | 否 | empty,1970~2099 | , - * / |
特殊字符的注释:
符号 | 注释 |
---|---|
* | 表示所有值, 例如:在分的字段上设置'*',表示每一分钟都会触发; |
? | 表示不指定值,使用的场景为不需要关心当前设置这个字段的值,例如需要在每月的10号执行,但不关心是周几;所以可以在周的字段上设置'?'; |
- | 表示区间.例如在小时上设置'10-12',表示10,11,12小时都会执行; |
, | 表示多指定多个值: 例如在周上指定'MON,WED,FRI'表示周一,周三,周五都会执行; |
/ | 用于递增触发,如在秒上面设置"5/15"表示从5秒开始,每隔15秒触发(5,20,35,50).在月上设置"1/3",每月1号开始,每隔3天触发一次; |
L | 表示最后的意思,在日上设置,表示当月最后一天(依据当前月份,如果是二月还依据当年是否是润年);在周字段上表示是星期六,相当于7或SAT; 如果在L前加数字,则表示该数据的最后一个,在周上设置'6L',表示本月最后一个星期五; |
W | 表示离指定日期最近的那个工作日(周一至周五).例如在日上设置'15W',表示离每月15号最近的那个工作日触发.如果15号正好是周六,则14号周五触发,如果15号是周日,则16号周一触发;如果15号是工作日,则当天触发; 设置为'1W',则表示每月一号后的工作日触发,如果1号为周六,则3号周一触发;(注: W前只能设置具体的数字,不能设置区间); |
# | 序号,表示每月的第几个周几, 在周上设置'6#3'表示在每月的第三个周五, 注意: '#5',当没有第五周的时候,不会触发该配置; |
提示: L,W 可以组合使用;
周字段英文字母不区分大小写;
利用工具在线生成: http://www.pdtools.net/tools/becron.jsp
StdSchedulerFactory :
(1), 使用一组参数(Java.util.Properties)来创建和初始化Quartz调度器;
(2), 配置参数一般存储在quartz.properties中;
(3), 调用getScheduler方法就能创建和初始化调度器对象;
Scheduler的主要函数:
(1), Date scheduleJob(JobDetail jobDetail, Trigger trigger); 返回最近一次将要触发的时间;
(2), void start(); 启动;
(3), void standby(); 挂起; 继续调用 start(),可以唤醒;
(4), void shutdown(); 关闭,不能被唤醒;
shutdown(true):表示等待所有正在执行的Job执行完毕后,再关闭scheduler;
shutdown(false):表示直接关闭scheduler;
quartz.properties :
文档的位置和加载顺序: 优先读取项目目录下的quartz.properties文件;如果没有,则读jar包;
组成部分: (1), 调度器属性; (2),线程池属性; (3),作业存储设施; (4),插件配置;
调度器属性:
org.quartz.scheduler.instanceName属性用来区分特定的调度器实例,可以按照功能用途来给调度器起名.
org.quartz.scheduler.instanceId属性和前者一样,也允许任何字符串,但这个值必须是在所有调度器实例中是唯一的,尤其是在一个集群当中,作为集群的唯一Key.假如你想Quartz帮你生成这个值的话,可以设置为AUTO;
示例:
package quartz;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
/**
*@description TODO CronTrigger日历时间调度
*@date 2018/1/23
*@author geYang
**/
public class HelloCronTrigger {
public static void main(String[] args) throws Exception {
Calendar calender = Calendar.getInstance();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob").build();
CronTrigger trigger = (CronTrigger)TriggerBuilder.newTrigger()
.withIdentity("myTrigger")
.withSchedule(CronScheduleBuilder.cronSchedule("0 0/1 10 ? * *"))
.build();
/**
* Cron 表达式:
* 用于配置CronTrigger实例.是由7个字表达式组成的字符串,描述了时间表的详细信息.格式: [秒] [分] [时] [日] [月] [周] [年]
* 例:
* 1,每秒中执行: "* * * * * ? *"
* 2,每天10点15分触发: "0 15 10 ? * *" ; "0 15 10 * * *"
* 3,每天下午的10:00~10:59,每隔五分钟执行一次: "0 0/1 10 * * ?"
* 4,周一到周五,每天上午10:15触发: "0 15 10 ? * 2-6" ; "0 15 10 ? * MON-FRI"
* 5,每月的第三周的星期五的10:15触发 : "0 15 10 ? * 6#3" (注: '6'=>星期五; '3'=>第三周 ; '6#3'=>第三周星期五)
* 6,从2017年到2018年每月最后一周的星期五的10:15分触发: "0 15 10 ? * 6L 2017-2018" (注: '6'=>星期五; 'L'=>最后一周; "6L"=>最后一周的星期五)
* 7,每天的 10:00~10:59以及 18:00~18:59每隔5秒执行一次: "0/5 * 10,18 * * ?"
* */
// 创建 Scheduler 实例;
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
scheduler.scheduleJob(jobDetail, trigger);
System.out.println("当前时间:"+sf.format(calender.getTime()));
scheduler.start();
}
}