笔记来源:IMOOC Java Quartz
Quartz 简介
- OpenSymphony 提供的强大的开源任务调度框架
- 纯 Java 实现,精细控制排程
-
Quartz 特点
- 强大的调度功能
- 灵活的应用方式
- 分布式和集群能力
-
主要用到的设计模式
- Builder 模式
- Factory 模式
- 组件模式
- 链式写法
-
Quartz 三个核心概念
- 调度器
- 任务
- 触发器
Quartz 体系结构
-
重要组成
- Job
- JobDetail
- JobBuilder
- JobStore
-
Trigger
- SimpleTrigger
- CronTrigger
- TriggerBuilder
- ThreadPool
- Scheduler
-
Calendar
- 一个Trigger 可以和多个Calendar 关联,以排除或包含某些时间点
-
监听器
- JobListener
- TriggerListener
- SchedulerListener
浅谈 Job
- Job 定义:实现业务逻辑的任务接口
- Job 接口非常容易实现,只有一个
execute
方法,类似TimerTask
的run
方法,在里面编写业务逻辑
package org.quartz;
public interface Job {
void execute(JobExecutionContext context) throws JobExecutionException;
}
-
Job 实例在 Quartz 中的生命周期
- 每次调度器执行 job 时,它在调用
execute
方法前会创建一个新的 job 实例 - 当调用完成后,关联的 job 对象实例会被释放,释放的实例会被垃圾回收机制回收
- 每次调度器执行 job 时,它在调用
浅谈 JobDetail
JobDetail
为 Job 实例提供了许多设置属性,以及 JobDataMap
成员变量属性,它用来存储特定 Job 实例的状态信息,调度器需要借助 JobDetail
对象来添加 Job 实例。
-
重要属性
name
group
jobClass
jobDataMap
浅谈 JobExecutionContext
- 当
Scheduler
调用一个 Job,就会将JobExecutionContext
传递给 Job 的execute()
方法; - Job 能通过
JobExecutionContext
对象访问到 Quartz 运行时候的环境以及 Job 本身的明细数据。
浅谈 JobDataMap
- 在进行任务调度时
JobDataMap
存储在JobExecutionContext
中,非常方便获取。 -
JobDataMap
可以用来装载任何可序列化的数据对象,当 job 实例对象被执行时这些参数对象会传递给它。 -
JobDataMap
实现了JDK的Map接口,并添加了一些非常方便的方法用来存取基本数据类型。 -
获取
JobDataMap
的两种方式- 从 Map 中直接获取
- Job 实现类中添加 setter 方法对应
JobDataMap
的键值(Quartz 框架默认的JobFactory
实现类在初始化 job 实例对象时会自动地调用这些 setter 方法)
浅谈 Trigger
- Quartz 中的触发器用来告诉调度程序作业什么时候触发。即
Trigger
对象是用来触发执行Job
的。 -
触发器通用属性
-
JobKey
:表示 job 实例的标识,触发器被触发时,该指定的 job 实例会执行。 -
StartTime
:表示触发器的时间表首次被触发的时间。它的值类型是java.util.Date
。 -
EndTime
:指定触发器的不再被触发的时间。
-
SimpleTrigger
- 在一个指定时间段内执行一次作业任务,或是在指定的时间间隔内多次执行作业任务。
-
withRepeatCount
重复次数可以是0
,正整数或是SimppleTrigger.REPEAT_INDEFINITELY
常量值。 -
withIntervalInSeconds
等重复执行间隔必须为0
或 长整数 - 一旦被指定了
endTime
参数,那么它会覆盖重复次数参数的效果
CronTrigger
-
CronTrigger
的作用:基于日历的作业调度器,而不是像SimpleTrigger
那样精确指定间隔时间,比SimpleTrigger
更常用。
Cron 表达式
- 用于配置
CronTrigger
实例; - 是由7个表达式组成的字符串,描述了时间表的详细信息;
- 格式:
[秒] [分] [时] [日] [月] [周] [年]
Cron 特殊字符
字段 | 是否必填 | 允许值 | 允许特殊字符 |
---|---|---|---|
秒 | 是 | 0~59 | , - * / |
分 | 是 | 0~59 | , - * / |
时 | 是 | 0~23 | , - * / |
日 | 是 | 1~31 | , - * ? / L W C |
月 | 是 | 1~12 或 JAN~DEC | , - * / |
周 | 是 | 1~7 或 SUN~SAT | , - * ? / L C # |
年 | 否 | empty 1970~2099 | , - * / |
Cron 表达式举例
表达式 | 含义 |
---|---|
0 15 10 ? | 每天10点15分触发 |
0 0/5 14 ? | 每天下午2点到2点59分(整点开始,每隔5分钟触发) |
0 15 10 ? * MON-FRI | 从周一到周五每天上午的10点15分触发 |
0 15 10 ? * 6#3 | 每月的第三周的星期五开始触发 |
0 15 10 ? 6L 2018-2019 | 从2018年到2019年每月最后一周的星期五10点15分触发 |
0/5 14,18 * ? | 每天14:00:00~14:59:55、18:00:00~18:59:55,每5秒触发一次 |
Cron 通配符说明
特殊字符 | 含义 |
---|---|
* | 表示所有值。例如:在[分]的字段上设置 *,表示每一分钟都会触发 |
? | 表示不指定值。使用的场景为不需要关系当前设置这个字段的值。例如:要在每月的10号触发一次,但不关心是周几,所有需要将[周]设置为 ?,具体设置为 0 0 0 10 * ?
|
- | 表示区间。例如:在[时]上设置 10-12,表示10、11、12点都会触发 |
, | 表示指定多个值。例如:在[周]上设置 MON,WED,FRI 表示周一、三、五触发 |
/ | 用于递增触发。例如:在[秒]上设置 5/15 表示从5秒开始,每增15秒触发(5、20、35、50)。又如在[月]上设置 1/3,表示每月1号开始,每隔三天触发 |
L | 表示最后的意思。在[日]字段上设置,表示当月的最后一天;在[周]字段上表示星期六(7 或 SAT);如果在L前加上数字,则表示该数据的最后一个。例如在[周]上设置 6L,表示“本月的最后一个星期五” |
W | 表示离指定日期最近那个工作日(周一至周五),例如在[日]字段上设置 15W,表示离每月15号最近的那个工作日触发。日光指定格式为 1W,则表示每月1号往后最近的工作日触发。(W前只能设置具体的数字,不允许区间-) |
# | +序号(表示每月的第几个周几),例如在[周]字段上设置 6#3 表示在每月的第三个周六,注意如果指定 #5,正好第五周没有周六,则不会触发该配置。(#用在母亲节和父亲节再适合不过了) |
-
L
和W
可以组合使用 - 周字段英文字母不区分大小写,即MON和mon相同
- 利用工具,在线生成
浅谈 Schedule
Scheduler - 工厂模式
-
所有的 Scheduler 实例应该由
SchedulerFactory
来创建-
SchedulerFactory
-StdSchedulerFactory
-
SchedulerFactory
-DirectSchedulerFactory
-
Scheduler 的创建方式
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
DirectSchedulerFactory factory = DirectSchedulerFactory.getInstance();
Scheduler scheduler = factory.getScheduler();
StdSchedulerFactory
- 使用一组参数
Java.util.Properties
来创建和初始化 Quartz 调度器 - 配置参数一般存储再
quartz.properties
中 - 调用
getScheduler
方法就能创建和初始化调度器对象
Scheduler 的主要函数
-
Date scheduleJob(JobDetail jobDetail, Trigger trigger)
- 返回此后第一次执行的时间
-
void start()
- 开始/继续执行 -
void standby()
- 挂起 -
void shutdown()
-
shutdown(true)
表示等待所有正在执行的 job 执行完毕之后,再关闭 scheduler -
shutdown(false)
即shutdown()
表示直接关闭 scheduler
-
quartz.properties
文档的位置和加载顺序
若项目无 quartz.properties
,将会去 quartz.jar
包读取默认 quartz.properties
。
组成部分
-
调度器属性
-
org.quartz.scheduler.instanceName
属性用来区分调度器实例,可以按功能用途来给调度器起名。 -
org.quartz.scheduler.instanceId
属性和前者一样,也允许任何字符串,但这个值必须是在所有调度器实例中是唯一的,尤其是在一个集群当中,作为集群的唯一key。假如你想 Quartz 帮你生成这个值的话,可以设置为AUTO
。
-
-
线程池属性
-
org.quartz.threadPool.threadCount
:指定线程数,至少为1(无默认值)(一般设置为1-100直接的整数合适) -
org.quartz.threadPool.threadPriority
:设置线程的优先级(最大为java.lang.Thread.MAX_PRIORITY
10,最小为Thread.MIN_PRIORITY
1,默认为5) -
org.quartz.threadPool.class
:线程池的实现类(一般使用SimpleThreadPool
可满足几乎所有用户的需求)
-
-
作业存储设置
- 描述了在调度器实例的生命周期中,Job 和 Trigger 信息是如何被存储的。
-
插件配置
- 满足特定需求用到的 Quartz 插件的配置。
- 相关例子代码:https://github.com/gcusky/lea...
- 较简单的 Java 定时任务调度工具:Timer
- Akka 利用 Extension 集成 Quartz:akka-quartz-scheduler
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。