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表达式是能够制定触发时间的一个格式

在这里插入图片描述

    • 表示任何值,如果在分的字段上编写*,表示每分钟都会触发
  • , 是个分割符如果秒字段我想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表示每月的第三个周五

    如果#后面数字写大了,是一个不存在的日期,那就不运行了

    适合设计在母亲节或父亲节这样的日期运行

推荐一个

https://cron.qqe2.com/

http://cron.ciding.cc/

每年双11运行

0 0 0 11 11 ?

每年的母亲节(5月份第三个周日)早上9点触发

0 0 9 ? 5 1#3

每个月10日18点发工资,如果10日是休息日,就在最近的工作日发

0 0 18 10W * ?

SpringBoot使用Quartz

SpringBoot框架下使用Quartz格式还是非常固定的

我们选用之前学习微服务的项目csmall减少对大项目的影响

首先添加依赖

我们选择csmall-stock-webapi模块pom文件

<!--   SpringBoot整合Quartz的依赖   -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

先编写要执行的任务

当前项目模块中创建quartz包

包中创建一个QuartzJob的类,实现Job接口

代码如下

@Slf4j
public class QuartzJob implements Job {

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        // 当前Job实现类只是为了测试Quartz的效果,所以操作简单一些即可
        log.info("----------------{}-----------------", LocalDateTime.now());
    }
}

上面编写的是Job接口的实现类,要想运行还需要将它封装为JobDetail对象保存在Spring容器中

还有要创建一个Trigger设置要运行的时机,也保存到Spring容器中

在quartz包下,再创建一个QuartzConfig类,其中编写它们的调度绑定关系

这个格式是固定的,后面再需要绑定,直接套用即可

// 我们要将Job和Trigger绑定在一起,明确触发关系
// 绑定成功后,会有Scheduler来调度,这个对象程序运行时会被SpringBoot创建
// 所以在配置中,我们只需要将JobDetail和Trigger对象保存到Spring容器即可
@Configuration
public class QuartzConfig {

    // @Bean注解标记的方法返回值会在SpringBoot项目启动时保存到Spring容器
    @Bean
    public JobDetail showTime(){
        // JobDetail类是专用于封装Job接口实现类的类型
        // JobBuilder.newJob就是管理Job接口实现类的方法
        return JobBuilder.newJob(QuartzJob.class)
                // 给当前任务起名,不能和其它任务重名
                .withIdentity("showTime")
                // 在默认情况下,JobDetail对象实例化后,没有Trigger绑定,可能会给GC回收
                // 设置storeDurably()方法后,JobDetail对象即使没有被绑定,也不会被回收
                .storeDurably()
                .build();
    }

    // Trigger对象也要保存到Spring容器
    @Bean
    public Trigger showTimeTrigger(){
        // 声明变量定义cron表达式
        CronScheduleBuilder cron=
                CronScheduleBuilder.cronSchedule("* * 17 28 4 ?");
        // 开始实例化返回Trigger对象
        return TriggerBuilder.newTrigger()
                // 绑定要触发的JobDetail对象
                .forJob(showTime())
                // 绑定cron表达式
                .withSchedule(cron)
                // 设置名称
                .withIdentity("showTimeTrigger")
                .build();
    }

}

Nacos\Seata需要启动

其他服务和软件都可以关闭

然后启动csmall-stock-webapi模块

观察控制台输出

@Slf4j
public class StockJob implements Job {

    @Autowired
    private StockMapper stockMapper;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        stockMapper.updateStockCount("PU201",2);
        log.info("库存减少完成!");
    }
}

配置类

@Bean
public JobDetail reduceStock(){
    return JobBuilder.newJob(StockJob.class)
            .withIdentity("reduceStock")
            .storeDurably()
            .build();
}

@Bean
public Trigger reduceStockTrigger(){
    CronScheduleBuilder cron=
            CronScheduleBuilder.cronSchedule("0/20 * * * * ?");
    return TriggerBuilder.newTrigger()
            .forJob(reduceStock())
            .withIdentity("reduceStockTrigger")
            .withSchedule(cron)
            .build();
}

Nacos\Seata需要启动

然后启动csmall-stock-webapi模块

观察控制台输出

也要观察数据库库存数变化

课上作业

csmall-stock模块

实现每隔20秒对当前数据库库存表中的某个商品(PU201)

库存数减少2的操作,同时在日志中输出"库存减少完成"

并观察数据库库存数是否变化

随笔

Schedule: 日程表

cache: 缓存

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值