一、定时任务含义

在很多情况下任务并非需要立即执行,而是需要往后或定期执行,这不可能人工去操作,所以定时任务就出现了。
使用定时任务的情况:
        每周末凌晨备份数据
        触发条件 5 分钟后发送邮件通知
        30 分钟未支付取消订单
        每 1 小时去拉取数据

二、搭建项目

1、新建模块

2、导入依赖

<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>

3、Scheduled(调度器)创建定时任务

在SpringBoot的启动类(Quartz01Application)类中加⼊ @EnableScheduling 注解,启⽤定时任务的配置

4、创建执行类

package com.lv.code;import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;@Component
@Slf4j
public class Task {@Scheduled(fixedRate = 1000)public void test(){log.warn("现在时间:" + LocalDateTime.now());}}

5、测试

每秒执行一次:

package com.lv.code;import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class Quartz01ApplicationTests {@Testvoid contextLoads() {while (true){}}}

 6、Scheduled参数

@Scheduled(fixedRate=5000):上⼀次开始执⾏时间点之后5秒再执⾏
@Scheduled(fixedDelay=5000):上⼀次执⾏完毕时间点之后5秒再执⾏
@Scheduled(initialDelay=1000, fixedRate=5000):第⼀次延迟1秒后执⾏,之后按fixedRate的规则每5秒执⾏⼀次
@Scheduled(cron="*/5 * * * * *"):通过cron表达式定义规则

cron表达式

cron表达式是一个字符串,以5或者6个空格隔开(示例中是被5个空格隔开),字符串被切割为6个或者7个域,每个域都代表不同的含义

注:日与星期不能同时出现,会矛盾,可以其中一个填?

星期里,1表示的是星期天,2表示的是星期一,以此类推,7表示的是星期六
?只存在于某天或某星期中,且不能同时存在(还不支持同时指定某天和星期)
'L'和'W'字符也可以在日期字段中组合以产生'LW',这转换为“最后一个工作日”
法定字符以及月份和星期的名称不区分大小写,如MON 与mon相同

{Seconds} {Minutes} {Hours} {DayofMonth} {Month} {DayofWeek} {Year}
{Seconds} {Minutes} {Hours} {DayofMonth} {Month} {DayofWeek}

 每个域都可以用数字表示,还可以出现如下特殊字符

* : 表示匹配该域的任意值,比如Minutes域使用*,就表示每分钟都会触发
- : 表示范围,比如Minutes域使用10-20,就表示从10分钟到20分钟每分钟都会触发一次
, : 表示列出枚举值,比如Minutes域使用1,3.就表示1分钟和3分钟都会触发一次
/ : 表示间隔时间触发(开始时间/时间间隔),例如在Minutes域使用 5/10,就表示从第5分钟开始,每隔10分钟触发一次
? : 表示不指定值,简单理解就是忽略该字段的值,直接根据另一个字段的值触发执行
# : 表示该月第n个星期x(x#n),仅用星期域,如:星期:6#3,表示该月的第三个星期五
L : 表示最后,是单词"last"的缩写(最后一天或最后一个星期几);仅出现在日和星期的域中,用在日则表示该月的最后一天,用在星期则表示该月的最后一个星期,如:星期域上的值为5L,则表示该月最后一个星期的星期四,在使用'L'时,不要指定列表','或范围'-',否则易导致出现意料之外的结果
W: 仅用在日的域中,表示距离当月给定日期最近的工作日(周一到周五),是单词"weekday"的缩写

例子:

0 */5 * * * ?   ——》在0秒开始,每隔5分钟执行一次

0 2,22,32 * * * ?  ——》在第2分钟,第22分钟和第32分钟的0秒都会执行一次

0 0 4-8 * * ?  ——》在第4个小时到第8个小时的0分0秒执行一次

0 0 2 1 * ?  ——》每个月的1号的2点钟0分0秒执行一次

0 0/5 14,18 * * ?  ——》每一天的14点和18点每隔5分钟执行一次

二、Quartz集成

1、Quartz创建定时任务

两种任务存储方式:这期内容讲解的是内存方式

内存方式(RAMJobStore):将任务临时存储到内存中,仅支持单项目部署,项目重启后任务会失效,不支持由调度器控制任务漂移,不建议使用。
数据库方式(JDBCJobStore): Quartz提供了多种数据库的所需表结构脚本,它内部通过 DataSource来操作数据,支持分布式方式部署、支持任务漂移,项目重启后任务不会丢失,直到任务执行完成后才会
被从数据库内清除。

2、导入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency>

3、测试类

Quartz01ApplicationTests:

package com.lv.code;import org.junit.jupiter.api.Test;import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.boot.test.context.SpringBootTest;import java.util.Date;import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;@SpringBootTest
class Quartz01ApplicationTests {@Testvoid contextLoads() throws Exception{
//        1、实例化调度器工厂SchedulerFactory factory=new StdSchedulerFactory();
//        2、得到调度器Scheduler scheduler = factory.getScheduler();
//        3、创建任务  newJob为静态方法,按住Alt+Enter,选择导入static方法JobDetail jobDetail = newJob(MyJob.class)
//                描述.withDescription("开年大扫除")
//                定义任务的主键:context.getJobDetail().getKey() = name + group,在同样的分组不能出现相同的名字,不同的名字则可以.withIdentity("大扫除", "厕所").usingJobData("name", "王阿姨")
//                同样可以用集合
//                JobDataMap jobDataMap=jobDetail.getJobDataMap();
//                jobDataMap.put("name","xx");
//                构建出来,一定要写.build();
//        4、创建触发器Trigger trigger = TriggerBuilder.newTrigger().withDescription("大扫除触发器").withIdentity("大扫除", "厕所").startAt(new Date())
//                .withSchedule(
//                        simpleSchedule()
//                        .withIntervalInSeconds(10)重复次数
//                        .withRepeatCount(10) //SimpleTrigger.REPEAT_INDEFINITELY
//                )
//        基于 Cron 表达式的触发器 CronTrigger.withSchedule(CronScheduleBuilder.cronSchedule("* * * * * ?")).build();
//      5、将触发器和任务绑定到调度器scheduler.scheduleJob(jobDetail, trigger);
//        6、启动调度器scheduler.start();}}

Scheduler 调度器:

用于与调度程序交互的主程序接口.
Scheduler维护了一个JobDetails和Triggers 的注册表。
一旦在Scheduler注册过了,当定时任务触发时间一到,调度程序就会负责执行预先定义的Job
调度程序创建之后,处于“待机”状态,必须调用 scheduler 的 start() 方法启用调度程序
可以使用 shutdown() 方法关闭调度程序,使用 isShutdown() 方法判断该调度程序是否已经处于关闭状态
通过 Scheduler.scheduleJob(…) 方法将任务纳入调度程序中,当任务触发时间到了的时候,该任务将被执行

实例化过程:

创建一个 Job 类,在调度程序中可以创建很多个 JobDetai,分别设置不同的 JobDataMap,JobBuilder 用于创建 JobDetail,如果没有调用 withIdentity 指定 job 的名字,会自动生成一个。

Trigger 触发器:

触发器使用 TriggerBuilder 来实例化,有一个 TriggerKey 关联,在一个 Scheduler 中必须是唯一的。多个触发器可以指向同一个工作,但一个触发器只能指向一个工作。
触发器可以传送数据给 job,通过将数据放进触发器的 JobDataMap。

触发器常用属性:

触发器也有很多属性,这些属性都是在使用 TriggerBuilder 定义触发器时设置的。
TriggerKey,唯一标识,在一个 Scheduler 中必须是唯一的
startTime,开始时间,通常使用 startAt(java.util.Date)
endTime,结束时间,设置了结束时间则在这之后,不再触发,                                           如果没有使用 withIdentity(..) 会自动生成一个触发器名称。

触发器的优先级:

有时候,会安排很多任务,但是 Quartz 并没有更多的资源去处理它。
这种情况下,必须需要很好地控制哪个任务先执行。这时候可以设置 priority 属性(使用方法
withPriority(int))来控制触发器的优先级。优先级只有触发器出发时间一样的时候才有意义。当一个任务请求恢复执行时,它的优先级和原始优先级是一样的。

常见触发器:

TriggerBuilder 用于创建 Trigger,如果没有调用 withSchedule(..) 方法,会使用默认的schedule 。
简单触发器 SimpleTrigger
SimpleTrigger 包含几个特点:开始时间、结束时间、重复次数以及重复执行的时间间隔。

基于 Cron 表达式的触发器 CronTrigger:

.withSchedule(CronScheduleBuilder.cronSchedule("2 * * * * *"))

4、Job 定时任务

任务是一个实现 org.quartz.Job 接口的类,任务类必须含有空构造器
当关联这个任务实例的触发器表明的执行时间到了的时候,调度程序 Scheduler 会调用这个方法来执行任务,任务内容就可以在这个方法中执行

新建Task 类: 

package com.lv.code;import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;@Component
@Slf4j
public class Task {@Scheduled(cron = "10 10 * * * ?")public void test(){log.warn("现在时间:" + LocalDateTime.now());}}

JobDataMap 提供了一种“初始化成员属性数据的机制”,在实现该 Job 接口的时候可以取到需要的数据

5、测试结果

本期内容结束~~~~

Quartz之基本使用相关推荐

  1. SpringBoot中实现quartz定时任务

    Quartz整合到SpringBoot(持久化到数据库) 背景 最近完成了一个小的后台管理系统的权限部分,想着要扩充点东西,并且刚好就完成了一个自动疫情填报系统,但是使用的定时任务是静态的,非常不利于 ...

  2. Java基于Quartz的定时任务调度服务(一)

    Quartz的基本用法 一 Quartz的简单介绍 Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现,一个优秀的开源调度框架,其特点是:强大的 ...

  3. springboot整合Quartz实现动态配置定时任务

    版权声明:本文为博主原创文章,转载请注明出处. https://blog.csdn.net/liuchuanhong1/article/details/60873295 前言 在我们日常的开发中,很多 ...

  4. Quartz 2D Programming Guide笔记

    ###Graphics Contexts图形上下文### 图形上下文(graphics context)是绘制目标,可以理解为画布,包含着绘图时的参数和设备信息.类型为CGContextRef.获取g ...

  5. 【Quartz】实现接口封装化(二)

    原文:[Quartz]实现接口封装化(二)   前言   通过昨天的努力终于算是了解Quartz这个定时器的简单使用,为了更深一步的了解和基于以后希望在项目中能使用他.所有我对他做了一下简单的封装操作 ...

  6. quartz在集群环境下的最终解决方案

    在集群环境下,大家会碰到一直困扰的问题,即多个 APP 下如何用 quartz 协调处理自动化 JOB . 大家想象一下,现在有 A , B , C3 台机器同时作为集群服务器对外统一提供 SERVI ...

  7. 将Quartz.NET集成到 Castle中

    Castle是针对.NET平台的一个开源项目,从数据访问框架ORM到IOC容器,再到WEB层的MVC框架.AOP,基本包括了整个开发过程中的所有东西,为我们快速的构建企业级的应用程序提供了很好的服务. ...

  8. 初识Quartz(三)

    为什么80%的码农都做不了架构师?>>>    简单作业: package quartz_project.example3;import java.util.Date;import ...

  9. java timer cron_Java之旅--定时任务(Timer、Quartz、Spring、LinuxCron)

    在Java中,实现定时任务有多种方式.本文介绍4种.Timer和TimerTask.Spring.QuartZ.Linux Cron. 以上4种实现定时任务的方式.Timer是最简单的.不须要不论什么 ...

  10. Quartz动态添加、修改和删除定时任务

    2019独角兽企业重金招聘Python工程师标准>>> Quartz动态添加.修改和删除定时任务 转载于:https://my.oschina.net/haokevin/blog/1 ...

最新文章

  1. 可编程led灯带原理_88张图搞定层板灯带的设计、安装、收口及检修!
  2. 阿里巴巴为什么要禁用 Executors 创建线程池?
  3. 关于windows10用c++部署libtorch过程中遇到的一些问题
  4. cmd命令将web项目打成jar包_2020全网首发!JDK14之jpackage命令尝鲜
  5. php模拟post提交请求与调用接口
  6. [原创].NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略
  7. java调用sql返回list_Spring JdbcTemplate实现有java.sql.ResultSet结果集返回的存储过程调用 | 学步园...
  8. Java基础学习总结(99)——Java代码性能优化总结
  9. 一.对ThreadLocal的理解
  10. Linux(CentOS)下安装tesseract-ocr以及配置依赖leptonica
  11. csharp:SQLite and Access using C# code read data
  12. 服务器进销财务管理系统,进销存财务管理系统
  13. 基于韦东山视频 regulator 学习笔记
  14. 【GIS教程】ArcGIS做日照分析(附练习数据下载)
  15. 罗技GHUB打开一直在加载怎么回事?
  16. 使用华硕N13u路由器配置共享打印机
  17. JavaCV实现视频人脸检测
  18. html、css、js文件加载顺序及执行情况
  19. 2021.11.9MySQL基本语句以及数据库于Unity的连接
  20. Java与CORBA技术结合的前景展望

热门文章

  1. tensor.squeeze函数和tensor.unsqueeze函数的使用
  2. 彻底理解面向对象,看完这一篇就够了
  3. JavaScript 常用字符串、数组、对象、判断类型方法
  4. Linux 进入root管理员权限
  5. 【C/C++】面经总结和心得分享
  6. Winform实时显示图像桌面程序
  7. python圣诞树代码成品图片动态_节日快乐! Python画一棵圣诞树送给你
  8. 电脑的桌面计算机在哪里,笔记本电脑上面的计算机在哪里?—详细步骤
  9. LightSwitch框架介绍
  10. 阶乘函数后K个零,详解