SpringBoot中实现quartz定时任务
Quartz整合到SpringBoot(持久化到数据库)
背景
最近完成了一个小的后台管理系统的权限部分,想着要扩充点东西,并且刚好就完成了一个自动疫情填报系统,但是使用的定时任务是静态的,非常不利于扩展和调控,就想到了用Quartz实现。
Quartz简介
Quartz
是一个优秀的任务调度框架,有静态任务调度和动态任务调度两种类型。静态任务调度是编写好代码,然后在启动的时候,将任务保存在内内存中,也就是下面的RAMJobStore
,实现相对简单;动态任务调度主要是持久化到数据库,即下面的JDBC作业存储
,实现方式相对复杂一点,但是可操作性更强。
- RAMJobStore :RAM也就是内存,默认情况下Quartz会将任务调度存在内存中,这种方式性能是最好的,因为内存的速度是最快的。不好的地方就是数据缺乏持久性,但程序崩溃或者重新发布的时候,所有运行信息都会丢失
- JDBC作业存储:存到数据库之后,可以做单点也可以做集群,当任务多了之后,可以统一进行管理。关闭或者重启服务器,运行的信息都不会丢失。缺点就是运行速度快慢取决于连接数据库的快慢。
Quartz相关概念
Scheduler:调度器,进行任务调度;quartz的大脑
Job:业务job,亦可称业务组件;定时任务的具体执行业务需要实现此接口,调度器会调用此接口的execute方法完成我们的定时业务
JobDetail:用来定义业务Job的实例,我们可以称之为quartz job,很多时候我们谈到的job指的是JobDetail
Trigger:触发器,用来定义一个指定的Job何时被执行
JobBuilder:Job构建器,用来定义或创建JobDetail的实例;JobDetail限定了只能是Job的实例
TriggerBuilder:触发器构建器,用来定义或创建触发器的实例
RAMJobStore的实现
整体流程
首先需要创建任务(Job),比如取消订单、定时发送短信邮件之类的,这是我们的任务主体,也是写业务逻辑的地方。
创建任务调度器(Scheduler),这是用来调度任务的,主要用于启动、停止、暂停、恢复等操作,也就是那几个api的用法。
创建任务明细(JobDetail),最开始我们编写好任务(Job)后,只是写好业务代码,并没有触发,这里需要用JobDetail来和之前创建的任务(Job)关联起来,便于执行。
创建触发器(Trigger),触发器是来定义任务的规则的,比如几点执行,几点结束,几分钟执行一次等等。这里触发器主要有两大类(SimpleTrigger和CronTrigger)。
根据Scheduler来启动JobDetail与Trigger
导入依赖
<!--quartz定时调度依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
创建Job
要求: 需实现Job接口,并且这个接口就一个execute()方法需要重写,方法内容就是具体的业务逻辑。如果是动态任务呢,比如取消订单,每次执行都是不同的订单号。这个时候就需要在创建任务(JobDetail)或者创建触发器(Trigger)的那里传入参数,然后在这里通过JobExecutionContext来获取参数进行处理,
/*** @author Mr.zhou* @version 1.0* @date 2020/11/17 17:52*/
public class TestJob implements Job {@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {System.err.println("Hello quartz, " + jobExecutionContext.getJobDetail().getJobDataMap().getString("message"));System.err.println("Hello quartz, " + jobExecutionContext.getMergedJobDataMap().getString("work"));System.err.println();}
}
创建任务调度器
这里我们用的是SpringBoot,SpringBoot会自动帮我们装配任务调度器,在使用的时候,直接注入即可。
@Resource
private Scheduler scheduler;
如果没用使用SpringBoot,那么就需要手动创建了。通常优秀的框架,创建某些核心类都会使用工厂模式或者构建者模式,值得学习。
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
创建任务明细:JobDetail
// 创建任务详情
JobDetail jobDetail = JobBuilder.newJob(TestJob.class)// 添加参数.usingJobData("message", "米西米西滑不拉几")// 添加认证信息,共有三种认证方式.withIdentity(orderNum).build();
创建触发器:Trigger
SimpleSchedule策略
// 创建触发器
Trigger trigger = TriggerBuilder.newTrigger()// 添加参数.usingJobData("work", "我在写代码,你呢?")// 认证信息.withIdentity(orderNum)// 开始时间.startAt(start)// 执行策率,有SimpleSchedule和CronSchedule两种.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).repeatForever()).build();
CronSchedule策略
// 创建触发器
Trigger trigger = TriggerBuilder.newTrigger()// 添加参数.usingJobData("work", "我在写代码,你呢?")// 认证信息.withIdentity(orderNum)// 开始时间.startNow()// 执行策率,有SimpleSchedule和CronSchedule两种.withSchedule(CronScheduleBuilder.cronSchedule("*/5 * * * * *")).build();
注意:.startNow()
和.startAt()
这里有个坑,这两个方法是对同一个成员变量进行修改的 也就是说startAt和startNow同时调用的时候任务开始的时间是按后面调用的方法为主的,谁写在后面用谁。看看这里的源码:
启动任务
上面都已经将工作完成了,接下来就是启动任务了
// 启动定时任务
scheduler.scheduleJob(jobDetail, trigger);
if (!scheduler.isShutdown()) {scheduler.start();
}
实现任务的常规操作
上面已经介绍了怎么去定义一个任务,并成功启动,下面就简单介绍任务的启动、暂停、恢复、以及删除等操作。
@RestController
@RequestMapping("/quartz")
public class QuartzController {@Resourceprivate Scheduler scheduler;/*** 启动一个定时任务* @param orderNum 编号* @return 结果* @throws SchedulerException 异常*/@PostMapping("/start")public R quartz(@RequestParam("orderNum") String orderNum) throws SchedulerException {// 当前时间10秒之后Date start = new Date(System.currentTimeMillis() + 10 * 1000);// 创建任务详情JobDetail jobDetail = JobBuilder.newJob(TestJob.class)// 添加参数.usingJobData("message", "米西米西滑不拉几")// 添加认证信息,共有三种认证方式.withIdentity(orderNum).build();// 创建触发器Trigger trigger = TriggerBuilder.newTrigger()// 添加参数.usingJobData("work", "我在写代码,你呢?")// 认证信息.withIdentity(orderNum)// 开始时间.startAt(start)// 执行策率,有SimpleSchedule和CronSchedule两种.withSchedule(CronScheduleBuilder.cronSchedule("*/5 * * * * ?")).build();// 启动定时任务scheduler.scheduleJob(jobDetail, trigger);if (!scheduler.isShutdown()) {scheduler.start();}System.err.println("定时任务启动成功");return R.ok();}/*** 任务关闭* @param oderNum 标识* @return 结果* @throws SchedulerException 异常*/@PostMapping("/shutdown")public R shutdown(@RequestParam("orderNum") String oderNum) throws SchedulerException {scheduler.pauseTrigger(TriggerKey.triggerKey(oderNum));return R.ok();}/*** 任务恢复* @param oderNum 标识* @return 结果* @throws SchedulerException 异常*/@PostMapping("/resume")public R resume(@RequestParam("orderNum") String oderNum) throws SchedulerException {scheduler.resumeTrigger(TriggerKey.triggerKey(oderNum));return R.ok();}/*** 任务删除* @param oderNum 标识* @return 结果* @throws SchedulerException 异常*/@PostMapping("/del")public R del(@RequestParam("/oderNum") String oderNum) throws SchedulerException {scheduler.pauseTrigger(TriggerKey.triggerKey(oderNum));scheduler.unscheduleJob(TriggerKey.triggerKey(oderNum));scheduler.deleteJob(JobKey.jobKey(oderNum));return R.ok();}}
结果示例
由于我项目已经集成了Swagger文档,所以我就直接在这上面进行接口测试了
开启任务
任务启动之后的输出效果
到这里,应该就清楚了Quartz和SpringBoot整合,大致流程,了解了RAMJobStore如何实现,那么数据库持久化的实现也应该有了基本思路了。
JDBC作业存储实现
大致流程
- 创建SpringBoot工程,并且加入Web和Quartz依赖
- 下载Quartz官方提供的数据库脚本,注意版本,并将其导入到自己项目的数据库中
- 添加Quartz配置
SpringBoot中实现quartz定时任务相关推荐
- java quartz管理,SpringBoot中使用Quartz管理定时任务的方法
定时任务在系统中用到的地方很多,例如每晚凌晨的数据备份,每小时获取第三方平台的 Token 信息等等,之前我们都是在项目中规定这个定时任务什么时候启动,到时间了便会自己启动,那么我们想要停止这个定时任 ...
- SpringBoot中整合Quartz
场景 项目搭建专栏: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/column/info/35688 简介 Quartz是OpenSymphony开源组织在Jo ...
- SpringBoot中的Quartz应用
Spring自带定时器任务: code: import org.springframework.beans.factory.annotation.Configurable; import org.sp ...
- springBoot下使用quartz定时任务;动态修改任务执行时间
先上依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spri ...
- Spring框架中的Quartz定时任务使用笔记(通过@Scheduled注解的方式实现)
1.修改spring的xml配置信息 applicationContext.xml 三个部分内容 1.xmlns添加:xmlns:task="http://www.springframewo ...
- springboot中如何创建定时任务,以及corn表达式规则
首先,需要在主启动类上添加@EnableScheduling注解,开启定时任务相关配置. @SpringBootApplication @EnableScheduling public class A ...
- springmvc中实现quartz定时任务
1.maven项目添加如下两个jar包,当然也需要相应的spring 的Jar <!-- Spring Quartz定时器 begin --><dependency><g ...
- hutool的定时任务不支持依赖注入怎么办_可调度定时任务在SpringBoot中的实践
定时任务在我们的项目中或多或少都会使用到,不论你是初级程序员,还是有多年工作经验的中高级程序员,在项目中加一个定时任务去处理业务的一个aspect,为什么用了一个英文单词'aspect'?而不是'切面 ...
- Springboot 使用quartz 定时任务 增删改查
前段时间公司项目用到了 定时任务 所以写了一篇定时任务的文章 ,浏览量还不错 , Springboot 整合定时任务 ) 所以就准备写第二篇, 如果你是一名Java工程师,你也可以会看到如下的页面 , ...
最新文章
- MySQL:一个死锁分析 (未分析出来的死锁)
- 皮一皮:一顿操作猛如虎...
- C++你不知道的那些事儿—C++语言的15个晦涩特性
- Jquery跳出each循环
- 从《爱莉克斯》说起,聊聊当前 VR 游戏设计的“困境”与“尝试”
- 【SAM】差异(P4248)
- 蚂蚁金服OceanBase挑战TPCC丨TPC-C基准测试之链路层优化
- 使用bat向文件的第一行中写入内容
- sql 执行 delete 的时候,结合子查询 exists ,怎样支持别名呢?
- ofo现在还有退路吗?
- 龙芯 python_在UOS20-龙芯(MIPS64EL)上安装 opencv-python
- android换肤的实现方案,Android换肤技术总结
- pdf 转化为jpg python 批量转化
- 自定义原生JS键盘快捷键和vue-hotkey
- 【Linux_02】
- Leco题目:整数反转
- AEJoy —— 详解 AE 如何将 png 序列帧导出为 SVGA 动画文件
- 项目型销售之定义与特点简介
- 刷机大师乐蛙定制版 v3.4.0 官方版
- linuxMint在虚拟机下装VMware Tolls