Quartz API

【定时任务框架Quartz】(一)Quartz入门与简单Demo搭建中我们其实已经提到了Quartz API的关键接口以及调度器Scheduler的生命期:

接口 含义
Scheduler 与调度程序交互的主要API
Job 你想要调度器执行的任务组件需要实现的接口
JobDetail 用于定义作业的实例
Trigger(即触发器) 定义执行给定作业的计划的组件
JobBuilder 用于定义/构建 JobDetail 实例,用于定义作业的实例
TriggerBuilder 用于定义/构建触发器实例

Scheduler 的生命期,从 SchedulerFactory 创建它时开始,到 Scheduler 调用shutdown() 方法时结束;
Scheduler 被创建后,可以增加、删除和列举 Job 和 Trigger,以及执行其它与调度相关的操作(如暂停 Trigger)。但是,Scheduler 只有在调用 start() 方法后,才会真正地触发 trigger(即执行 job)

同时在第一篇的末尾,提到demo中使用的三个“builder”JobBuilder TriggerBuilder SimpleScheduleBuilder 也提到其实他们就是java设计模式中的<mark>建造者</mark>,我们可以这么理解,建造者的任务就是为我们创建好对象实例,供我们去使用,具体可以看第一篇。

除此以外,Quartz还为我们提供了其他的builder:

SchedulerBuilder 接口的各种实现类,可以定义不同类型的调度计划 (schedule);

DateBuilder 类包含很多方法,可以很方便地构造表示不同时间点的 java.util.Date 实例(如定义下一个小时为偶数的时间点,如果当前时间为 9:43:27,则定义的时间为10:00:00)
注意:
SchedulerFactory和SchedulerBuilder的区别和使用

Job 和 Trigger

第一篇提到我们首先要确定一个Job(定时任务)比如购票检查时间是否超时、合同到期提醒等等,一个 Job 就是一个实现了 Job 接口的类,这个Job接口只有一个方法。这个方法就是一个任务的核心内容,它在某一时刻需要做什么操作都是写在这个方法中。
接口:

public interface Job {
   
    public void execute(JobExecutionContext context) throws JobExecutionException;
  }

实例:

public class PrintWordsJob implements Job {
   
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
   
        String printTime = new SimpleDateFormat("yy-MM-dd HH-mm-ss").format(new Date());
        System.out.println("PrintWordsJob start at:" + printTime + ", prints: Hello Job-" + new Random().nextInt(100));
    }
}

<mark>JobDetail</mark> 对象是在将 job 加入 scheduler 时,由客户端程序(你的程序)创建的。它包含 job 的各种属性设置,以及用于存储 job 实例状态信息的 JobDataMap。
说白了就是,客户端必须要指定你的定时任务是哪个,JobDetail其实就是一个具体的调度任务
例如第一篇的demo:

在创建一个具体的调度任务的时候,我们可以看到,首先newJob会指定绑定哪一个Job执行内容,然后就是有一个指定Identity(job的名称以及分组名)称为Key

将 Job 和 Trigger 注册到 Scheduler 时,可以为它们设置 key,配置其身份属性。 Job 和 Trigger 的 key(JobKey 和 TriggerKey)可以用于将 Job 和 Trigger 放到不同的分组(group)里,然后基于分组进行操作。同一个分组下的 Job 或 Trigger 的名称必须唯一,即一个 Job 或 Trigger 的 key 由名称(name)和分组(group)组成。

<mark>Trigger</mark> 用于触发 Job 的执行。当你准备调度一个 job 时,你创建一个 Trigger 的实例,然后设置调度相关的属性。Trigger 也有一个相关联的 JobDataMap,用于给 Job 传递一些触发相关的参数。Quartz 自带了各种不同类型的 Trigger,最常用的主要是 SimpleTrigger 和 CronTrigger。

SimpleTrigger 主要用于一次性执行的 Job(只在某个特定的时间点执行一次),或者 Job 在特定的时间点执行,重复执行 N 次,每次执行间隔T个时间单位。CronTrigger 在基于日历的调度上非常有用,如“每个星期五的正午”,或者“每月的第十天的上午 10:15”等。
CronTrigger 是基于Cron表达式的,先了解下Cron表达式:

[秒] [分] [小时] [日] [月] [周] [年]

例如:00 00 00 ? * 10,11,12 1#5 2018
表示2018年10、11、12月的第一周的星期五这一天的0时0分0秒去执行任务
是不是非常的头疼。没关系,已经有很好的线上工具帮我们生成:
例如:该cron表达式的意思就是每年的1、2、3、4、6月的1号0点0分0秒去执行任务

在线工具地址https://cron.qqe2.com/
关于CronTrigger如何使用,将在后面的文章中体现出来。

那为什么既有 Job,又有 Trigger 呢?
调度和要调度的任务分离是合理的,可以带来很多好处:

例如,Job 被创建后,可以保存在 Scheduler 中,与 Trigger 是独立的,同一个 Job可以有多个 Trigger;这种松耦合的另一个好处是,当与 Scheduler 中的 Job 关联的 trigger 都过期时,可以配置 Job 稍后被重新调度,而不用重新定义 Job;还有,可以修改或者替换 Trigger,而不用重新定义与之关联的 Job。

简单的来说就是某个具体任务只需要写好一个Job,然后可以创建多个触发器去调用,因为我们知道在设置触发器的时候,是可以设置时间的,Job和触发器互不相干的话,我们可以按照需求只改动调用这个任务的时间即可。

如果文章对你有帮助,不要忘了给我点个赞吼( ̄▽ ̄)~
欢迎大家关注我的微信公众号:松鼠技术站