Quartz 定时任务框架的基本使用

概述

简单的来说,Quartz就是一个做定时任务的东西。举个简单的例子。想如果我们使用花呗去买东西的话,支付宝一般会在每个月的三号、四号去统计账单然后发送到你的支付宝之上,那么这个任务不可能是人工手动去执行的,一般都是设置好的程序去自动进行「任务」。

Quartz就是这样一个第三方的框架。

基本概念

Quartz的主要核心就分为四块。

  • Scheduiler 调度器
  • Job 任务
  • JobDetail 任务的包装
  • Trigger 触发器

首先,我们的所谓Scheduiler其实就是「管理、协调」我们设置的任务集合。

而Job则是任务的实现,我们基于它去做一些操作,如同上述,我们在 Job 中编写「账单的统计与发送」。值得注意的是,Job 只是一个单纯的任务 ,它就只是对具体的操作做了一个封装,然后我们需要通过JobDetail来创建一个「真正的任务」。
简单的来说,单纯的 Job不具备「被管理的能力」,而我们需要JobDetail来对其进行封装。

最后,Trigger 就很简单的,它负责去触发任务。比如我们在触发器中设置每两秒执行某个操作,那么当触发器到这个设置的时候,就会去触发对应的任务。

使用

pom

    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.2.1</version>
    </dependency>

代码

简单的触发方式

根据上述概念我们可以知道,我们应该先创建一个 Job 任务。

所以我们创建了我们的第一个 Job 任务类,名称为「FirstJob」,我们需要对其实现「org.quartz.Job」包下的 JOb接口并实现其中的「execute」方法,我们的具体操作就是要写在这个方法之内。

public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
    System.out.println("hi first job:" + new Date());
}

然后我们需要创建一个主程序去创建调度器、触发器,然后去执行这个任务~

我们首先通过调度器的工厂方法创建了一个调度器,再通过「TriggerBuilder」构造类创建了一个触发器。

首先,为了方便管理,我们使用了「withIdentity」来声明这个触发器的名称和组别。然后对其设置「任务开始时间 startNow()」和「任务结束时间 endAt()」。
并且我们通过「withSchedule」方法设置了具体的操作时间。我们在其中使用「SimpleScheduleBuilder」构造类去构造一个时间计划,使用「withIntervalInSeconds」设置两秒钟做一次执行(当然,肯定不止这一种,我们也可以设置两分钟执行一次、两个小时执行一次,等),然后使用「repeatForever」声明一直会循环执行到「endAt」声明的时间。

我们也可以通过「withRepeatCount」设置具体的执行次数。当然,如果到了结束时间之后还是没有达到我们设置的次数,任务也会直接结束掉。

    //调度器
    Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
    
    //触发器
    SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "gruop1")
            .startNow()
            .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever())
            .endAt(new GregorianCalendar(2021, 5, 2, 1, 5, 2).getTime())
            .build();
    //封装成 JobDetail 并给它设置名称和组名
    JobDetail jobDetail = JobBuilder.newJob(FirstJob.class).withIdentity("job1", "group1").build();
    
    //添加任务
    scheduler.scheduleJob(jobDetail,trigger);
    
    //启动任务
    scheduler.start();

Cron 表达式

上述中我们使用了简单的方式来创建了一个触发器,并且完成了每两秒执行一次 Job 的操作。但是我们平时的真实业务操作并不只是这样去设计,而是更为复杂。

具体介绍可见:https://baike.baidu.com/item/cron/10952601?fr=aladdin#3

cron表达式.png
如,我们想要在每个月的3号的十点零分零秒来执行一次任务,那么表达式就是:「 0 0 10 3 * ?」。

在其中有三个特殊的符号。

「l」 代表 last,最后一个的意思。
如, 「11 21 3 l 2 ?」代表二月的最后一天的三点二十一分十一秒。

「w」 代表 work,代表最近的工作日。
如, 「11 21 3 13w 2 ?」代表二月中离13号最近的工作日的三点二十一分十一秒。但值得注意的是,它不能进行跨月,只能在当前月计算。

「#」 在星期中使用,如 「2#3」代表第三个星期一。

那么我们在代码中应该如何运用呢?

大体同前述代码大抵相同,只是在触发器构建中有些诧异。

    CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "gruop1")
        .withSchedule(CronScheduleBuilder.cronSchedule("*/2 * * * * ?"))
        .build();

很显然,我们去除了开始时间和结束时间,因为我们不需要这个。此表达式就表示,从现在开始,每隔两秒就执行一次

最后

当然,本篇博文只是关于 Quartz 的基本使用,后续还需要学习整合到Springboot和动态添加任务。

# Quratz