Quartz
什么是Quartz
quartz:石英钟的意思
是一个当今市面上流行的高效的任务调度管理工具
所谓"调度"就是制定好的什么时间做什么事情的计划
由OpenSymphony开源组织开发
Symphony:交响乐
是java编写的,我们使用时需要导入依赖即可
为什么需要Quartz
所谓"调度"就是制定好的什么时间做什么事情的计划
我们使用过的最简单的调度方法就是Timer
但是Timer的调度功能过于单一,只能是指定时间的延时调用和周期运行
而Quartz可以更详细的指定时间,进行计划调用
Quartz核心组件
调度器:Scheduler
任务:job
触发器:Trigger
调度器来配置\计划什么时间触发什么任务
简单来说就是调度器规定什么时间做什么事情
job(工作\任务):Quartz 实现过程中是一个接口,接口中有一个方法execute(执行的意思)
我们创建一个类,实现这个接口,在方法中编写要进行的操作(执行具体任务)
我们还需要一个JobDetail的类型的对象,Quartz每次执行job时
会实例化job类型对象,去调用这个方法,JobDetail是用来描述Job实现类的静态信息,
比如任务运行时在Quartz中的名称
Trigger(触发器):能够描述触发指定job的规则,分为简单触发和复杂触发
简单触发可以使用SimplTrigger实现类.功能类似timer
复杂触发可以使用CronTrigger实现类,内部利用cron表达式描述各种复杂的时间调度计划
Scheduler(调度器):一个可以规定哪个触发器绑定哪个job的容器
在调度器中保存全部的Quartz 保存的任务
SpringBoot框架下,添加Quartz依赖后,调度器由SpringBoot管理,我们不需要编写
Cron表达式
Cron表达式是能够制定触发时间的一个格式
表示2023年2月3日凌晨4点触发的cron表达式
0 0 4 3 2 ? 2023
* 表示任何值,如果在分的字段上编写*,表示每分钟都会触发
, 是个分割符如果秒字段我想20秒和40秒时触发两次就写 20,40
- 表示一个区间 秒字段5-10 表示 5,6,7,8,9,10
/ 表示递增触发 秒字段 5/10表示5秒开始每隔10秒触发一次
日字段编写1/3表示从每月1日起每隔3天触发一次
? 表示不确定值, 因为我们在定日期时,一般确定日期就不确定是周几,相反确定周几时就不确定日期
L 表示last最后的意思,我们可以设置当月的最后一天,就会在日字段用L表示,
周字段使用L表示本月的最后一个周几,一般会和1-7的数字组合
例如6L表示本月的最后一个周五
W (work)表示最近的工作日(单纯的周一到周五) 如果日字段编写15W表示
每月15日最近的工作日触发,如果15日是周六就14日触发,如果15日是周日就16日触发
LW通常一起使用,表示本月的最后一个工作日
# 表示第几个,只能使用在周字段上 6#3表示每月的第三个周五
如果#后面数字写大了,是一个不存在的日期,那就不运行了
适合设计在母亲节或父亲节这样的日期运行
推荐一个http://cron.ciding.cc/
每年的母亲节(5月份第三个周日)早上9点触发
0 0 9 ? 5 1#3
每个月10日发工资如果10日是休息日,就在最近的工作日发,早上9点触发
0 0 9 10W * ?
每年双11运行 上午11点运行
0 0 11 11 11 ?
SpringBoot使用Quartz
SpringBoot框架下使用Quartz格式还是非常固定的
我们选用之前学习微服务的项目csmall减少对大项目的影响
首先添加依赖
我们选择csmall-stock-webapi模块pom文件
<!-- Spring Boot 整合 Quartz的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
先编写要执行的任务
当前项目模块中创建quartz包
包中创建一个QuartzJob的类,实现Job接口
代码如下
@Slf4j
public class QuartzJob implements Job {
// 这个方法就是当前job要定时执行的任务方法
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
// 因为当前是简单演示功能,所以就输出一个当前时间即可
log.info("-----------------"+ LocalDateTime.now() +"-------------------");
}
}
上面编写的是Job接口的实现类,要想运行还需要将它封装为JobDetail对象保存在Spring容器中
还有要创建一个Trigger设置要运行的时机,也保存到Spring容器中
在quartz包下,再创建一个QuartzConfig类,其中编写它们的调度绑定关系
这个格式是固定的,后面再需要绑定,直接套用即可
// QuartzConfig类用于配置绑定调用的方法和触发的关系
// 这个触发实际上会由Spring容器中的Scheduler对象调度
// 下面开始配置,Spring所有配置类都需要添加@Configuration
@Configuration
public class QuartzConfig {
// 配置本身的目的就是将Job对象和Trigger对象保存到Spring容器中让Scheduler来调度
// 可以利用@Bean注解,将上述两个对象保存Spring容器中
@Bean
public JobDetail showTime(){
// JobDetail对象配置时,需要将欲触发的Job接口实现类配置出来
// JobBuilder.newJob方法是可以创建JobDetail对象的,方法参数就是Job接口实习类的反射
// 后面触发这个方法时,每次触发都会实例化一个新的QuartzJob对象运行
return JobBuilder.newJob(QuartzJob.class)
// 给当前任务起名,不要和其它任务名称重复即可
.withIdentity("dateTime")
// 默认情况下JobDetail对象生成后,如果没有触发器绑定就会自动移除
// 在实际运行时,JobDetail实例化出来,没有绑定就被移除了
// 设置storeDurably方法之后,JobDetail即使没有被绑定,也不会被删除了
.storeDurably()
.build();
}
// 要想实现"什么时间做什么事情"还需要配置时间的计划
// 下面开始配置Trigger触发器的对象,绑定上面的JobDetail
@Bean
public Trigger showTimeTrigger(){
// 声明Corn表达式,定义触发时间
CronScheduleBuilder cron=
CronScheduleBuilder.cronSchedule("0 38 14 2 2 ?");
return TriggerBuilder.newTrigger()
// 设置要绑定的JobDetail对象
.forJob(showTime())
// 当前触发器也要起名字,名字也是不要重复出现的
.withIdentity("dateTimeTrigger")
// 绑定cron表达式
.withSchedule(cron)
.build();
}
}