文档:www.w3cschool.cn/quartz_doc/…
注意
一旦调度器(Scheduler)实例化后,它就能够启动,等待执行和关闭。需要注意的是一旦调度器调用 了shutdown 方法关闭后,如果不重新实例化,它就不会启动了。触发器在调度器未启动时,或是终止状态时,都不会被触发。
Quartz API的关键接口是:
- Scheduler - 与调度程序交互的主要Api
- Job - 你想要调度执行的任务组件需要实现的接口
- JobDetial - 用于定义作业实例。
- Trigger(即触发器)-定义执行给定作业的计划的组件。
- JobBuilder - 用于定义/构建JobDetail实例,用于定义作业的实例
- TriggerBuilder - 用于定义/构建触发器实例。
Scheduler的生命周期
从 SchedulerFactory 创建它时开始,到 Scheduler 调用shutdown() 方法时结束;Scheduler 被创建后,可以增加、删除和列举 Job 和 Trigger,以及执行其它与调度相关的操作(如暂停 Trigger)。但是,Scheduler 只有在调用 start() 方法后,才会真正地触发 trigger(即执行 job)
Job 和 Trigger
一个 job 就是一个实现了 Job 接口的类,该接口只有一个方法:
Job 接口:
package org.quartz;
public interface Job {
public void execute(JobExecutionContext context)throws JobExecutionException;
}
JobDetail 对象是在将 job 加入 scheduler 时,由客户端程序(你的程序)创建的。它包含 job 的各种属性设置,以及用于存储 job 实例状态信息的 JobDataMap。
Trigger 用于触发 Job 的执行。当你准备调度一个 job 时,你创建一个 Trigger 的实例,然后设置调度相关的属性。Trigger 也有一个相关联的 JobDataMap,用于给 Job 传递一些触发相关的参数。
Quartz 自带了各种不同类型的 Trigger,最常用的主要是 SimpleTrigger 和 CronTrigger。
SimpleTrigger 主要用于一次性执行的 Job(只在某个特定的时间点执行一次),或者 Job 在特定的时间点执行,重复执行 N 次,每次执行间隔T个时间单位。CronTrigger 在基于日历的调度上非常有用,如“每个星期五的正午”,或者“每月的第十天的上午 10:15”等。
Key
将 Job 和 Trigger 注册到 Scheduler 时,可以为它们设置 key,配置其身份属性。 Job 和 Trigger 的 key(JobKey 和 TriggerKey)可以用于将 Job 和 Trigger 放到不同的分组(group)里,然后基于分组进行操作。同一个分组下的 Job 或 Trigger 的名称必须唯一,即一个 Job 或 Trigger 的 key 由名称(name)和分组(group)组成。
3、Job与JobDetail介绍
JobDetail job = newJob(HelloJob.class)
.withIdentity("myJob", "group1") // name "myJob", group "group1"
.build();
--------
public JobDetail build() {
JobDetailImpl job = new JobDetailImpl();
job.setJobClass(this.jobClass);
job.setDescription(this.description);
if (this.key == null) {
this.key = new JobKey(Key.createUniqueName((String)null), (String)null);
}
job.setKey(this.key);
job.setDurability(this.durability);
job.setRequestsRecovery(this.shouldRecover);
if (!this.jobDataMap.isEmpty()) {
job.setJobDataMap(this.jobDataMap);
}
return job;
}
-------
// Tell quartz to schedule the job using our trigger
sched.scheduleJob(job, trigger);
可以看到,我们传给scheduler一个JobDetail实例,因为我们在创建JobDetail时,将要执行的job的类名传给了JobDetail,所以scheduler就知道了要执行何种类型的job;每次当scheduler执行job时,在调用其execute(…)方法之前会创建该类的一个新的实例;执行完毕,对该实例的引用就被丢弃了,实例会被垃圾回收;这种执行策略带来的一个后果是,job必须有一个无参的构造函数(当使用默认的JobFactory时);另一个后果是,在job类中,不应该定义有状态的数据属性,因为在job的多次执行中,这些属性的值不会保留。
JobDataMap
JobDataMap中可以包含不限量的(序列化的)数据对象,在job实例执行的时候,可以使用其中的数据;JobDataMap是Java Map接口的一个实现,额外增加了一些便于存取基本类型的数据的方法。
将job加入到scheduler之前,在构建JobDetail时,可以将数据放入JobDataMap,如下示例:
// define the job and tie it to our DumbJob class
JobDetail job = newJob(DumbJob.class)
.withIdentity("myJob", "group1") // name "myJob", group "group1"
.usingJobData("jobSays", "Hello World!")
.usingJobData("myFloatValue", 3.141f)
.build();
在job的执行过程中,可以从JobDataMap中取出数据,如下示例:
JobExecutionException
最后,是关于Job.execute(..)方法的一些额外细节。execute方法中仅允许抛出一种类型的异常(包括RuntimeExceptions),即JobExecutionException。因此,你应该将execute方法中的所有内容都放到一个”try-catch”块中。你也应该花点时间看看JobExecutionException的文档,因为你的job可以使用该异常告诉scheduler,你希望如何来处理发生的异常。
4、Quartz中Triggers介绍
Trigger的公共属性
所有类型的trigger都有TriggerKey这个属性,表示trigger的身份;除此之外,trigger还有很多其它的公共属性。这些属性,在构建trigger的时候可以通过TriggerBuilder设置。
trigger的公共属性有:
- jobKey属性:当trigger触发时被执行的job的身份;
- startTime属性:设置trigger第一次触发的时间;该属性的值是java.util.Date类型,表示某个指定的时间点;有些类型的trigger,会在设置的startTime时立即触发,有些类型的trigger,表示其触发是在startTime之后开始生效。比如,现在是1月份,你设置了一个trigger–“在每个月的第5天执行”,然后你将startTime属性设置为4月1号,则该trigger第一次触发会是在几个月以后了(即4月5号)。
- endTime属性:表示trigger失效的时间点。比如,”每月第5天执行”的trigger,如果其endTime是7月1号,则其最后一次执行时间是6月5号。
优先级(priority)
注意:只有同时触发的trigger之间才会比较优先级。10:59触发的trigger总是在11:00触发的trigger之前执行。
注意:如果trigger是可恢复的,在恢复后再调度时,优先级与原trigger是一样的。
错过触发(misfire Instructions)
日历示例(calendar)
Calendar用于从trigger的调度计划中排除时间段。
5、Simple Trigger
Spring Quartz使用教程 juejin.cn/post/684490…
待办
DSL,Domain Specific Language