返回顶部
首页 > 资讯 > 后端开发 > JAVA >Java开发 - Quartz初体验
  • 124
分享到

Java开发 - Quartz初体验

Quart任务调度schedulingJobJobDetail 2023-09-07 20:09:24 124人浏览 薄情痞子
摘要

目录​​​​​​​ 前言 Quartz 什么是Quartz Quartz作用 Quartz结构 表达式 案例 Quartz实战 添加依赖 创建Job类 创建配置类 测试代码 扩展练习 结语 前言 在上一篇博客中,我们对单点登录有了初步了

目录​​​​​​​

前言

Quartz

什么是Quartz

Quartz作用

Quartz结构

表达式

案例

Quartz实战

添加依赖

创建Job类

创建配置类

测试代码

扩展练习

结语


前言

在上一篇博客中,我们对单点登录有了初步了解,这也让我们独立做系统有了最基础的保障。但在业务开发中,总是会出现一些定期处理的任务,我们首先想到的是Timer,但由于其调度功能单一,我们实际并不会用它来做项目中的任务调度。今天我们就针对定期任务来说说Quartz这个时间调度工具和它的具体用法。

Quartz

什么是Quartz

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Quartz 允许程序开发人员根据时间的间隔来调度作业,它实现了作业和触发器的多对多的关系,还能把多个作业与不同的触发器关联。听起来好可怕,功能也太强大了。但从字里行间我们还是读出来,它主要是用于延时的。

Quartz作用

上面我们说,Quartz主要用于延时,这么说没错,也是其最本质的功能,但它还有一个强大的功能:任务调度。因为它并不是只针对某一个任务,而是针对成千上万的任务,就像一个强的控制中心,我们称之为调度。

我们知道,城市的公交地铁是有调度中心的,他们都是按照某些固定的规律来运行,比如间隔多久发一趟车,更高级的会有动态调度,这恐怕超过了我们今天要说的范畴。

之所以不使用Timer而使用Quartz,是因为Quartz有着更加便捷的时间指定方式。比如,每月1号执行一个任务,可以想想Timer要怎么做?是不是要计算每月的天数,往大了还有平年闰年,而Quartz则不用这么麻烦,两相比较,Quartz成了最好的选择。

Quartz结构

在继续讲下去之前,我们要先知道Quartz的几个核心概念,了解了这几个组件,有助于我们更好地理解Quartz的工作原理。

  1. Job 表示一个工作,要执行的具体内容。此接口中只有一个方法,如下:
    void execute(JobExecutionContext context) 

    一般是创建一个类,继承此接口,重写内部方法来执行一些具体的任务。

  2. JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。通俗的讲,Quartz每次执行job时,job类型对象会被实例化,上面的方法会被调用,JobDetail则用来描述其静态信息,我们会在下面的案例中进行使用。
  3. Trigger 代表一个调度参数的配置,表示什么时候去调。简单触发可以使用SimplTrigger实现类,其功能类似timer。复杂触发可以使用CronTrigger实现类,其内部利用cron表达式描述各种复杂的时间调度计划,这个用的比较多。
  4. Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler容器调度了。SpringBoot框架下,添加Quartz依赖后,调度器将由springBoot管理,开发者不需要编写其代码,Spring Boot再次为我们简化了步骤,让我们为其鼓掌,还有谁不会使用Spring Boot的,欢迎查看博主文章:Java开发 - 问君能有几多愁,Spring Boot瞅一瞅

看到这里,Quartz我们就了解了大半了,听起来很像移动端的通知,或者叫广播,也很像Nacos的注册服务,总之服务一定要注册才能被统一管理。你会发现,统一管理的理念就是一定要知道注册方和调用方是谁才能正常的工作,否则就全乱套了。
 

表达式

序号时间单位必填/选填值范围可选通配符
1必填0~59,-*/
2必填0~59,-*/
3必填0~23,-*/
4必填1~31,-*/?LW
5必填1~12/JAN~DEC,-*/
6必填1~7/SUN~SAT,-*/?L#
7选填empty/1970~2099,-*/
  • ,是分割符,假如我想在每分钟里的20s和40s分别触发一次,就可以这么写:20,40
  • -表示一个区间,以秒为例,1-5表示在1,2,3,4,5秒都触发
  • *表示任何值,在秒那里写就代表每秒都触发,在分那里写就代表每分都触发,依此类推 
  • /表示递增触发,以秒为例,1/20表示从第1秒开始每20秒触发一次,在其他单位上依此类推
  • ?表示不确定值,比如我们在确定了具体日期后,就不确定是周几,还要去算,可以用?代替,反之亦然
  • L表示最后,设置当月的最后一天就在日字段用L表示,周字段使用L就表示最后一周,一般会和1-7的数字组合,2L就是每月最后一周的星期二
  • W表示离某一天最近的工作日(工作日:周一~周五),只能用在日上面,10W则表示离10号最近的工作日,10号是工作日就10号触发,是周六就周五触发,周日就周一触发,LW通常一起使用,表示每月最后一天工作日,有些公司是每月最后一个工作日发工资,系统内就可以用这个通配符
  • #表示第几个,只能用在周字段,用来写父亲节,母亲节这些第几个周几,最合适不过。7#2表示每月的第二个周日,当然,要写古琴姐母亲节还要指定固定月份,我们稍后可以写写看,需要注意的是,#后面的数字写大了,超出了当月最大天数就不会执行了

案例

双十一写法:0 0 0 11 11 ?

每月最后一个工作日写法:0 0 0 LW * ?

父亲节写法:0 0 0 * 6 7#3  父亲节是每年6月的第3个星期日,看看解析结果:

不确定对不对的小伙伴可以去对日历看看,哈哈。

国庆节写法:0 0 0 1 10 * 

写的有点停不下来,真是太有意思了。大家可以自己写写看,从左到右要和:秒,分,时,日,月,周,年一一对应,最后一个年可以不写,如果是每年的话,你就是加个*也是可以的,因为指定具体年份貌似没有意义,一般都是当年,你不可能今年安排明年的活动,即使年底12月,预约下一年12月前的日期,也不需要写年份如果你当年11月预约下年12月的活动,那就需要写具体年份,但你不觉得这样很不礼貌吗?

反解析Cron工具地址给大家贴一个:Cron - 在线Cron表达式生成器

类似的工具还有很多,根据自己喜好选择即可。 

Quartz实战

下面,我们要在Spring Boot项目中来进行接入,就以我们前文中微服务项目为模版,新朋友没有一跟着做前面教程的话也可单独建项目来接入,并不会有什么影响。

添加依赖

我们选择在cloud-stock子工程下引入Quartz依赖:

    org.springframework.boot    spring-boot-starter-quartz

单独建项目的童鞋根据后续使用需要再自行引入其他的依赖,后续不再针对依赖引入做额外说明。 

创建Job类

在stock子项目下创建quartz包,包下创建QuartzJob类:

以后默认子项目下创建包都是在主包下,启动文件同级别目录创建,万万不要创建在src之外。在其他包下创建会说明的,之前就出现有童鞋创建错位置的情况,作为一名Java开发工程师,这个是 不应该的。

看看这个类中的代码:

package com.codingfire.cloud.stock.quartz;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import java.time.LocalDateTime;public class QuartzJob implements Job {    @Override    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {        //输出当前时间        System.out.println("--------------"+ LocalDateTime.now() +"---------------");    }}

暂不做任何处置,只是重写了前面提到的 execute方法,因为Job会执行此方法,重写可以做一些其他操作,此处暂时只输出当前时间。

创建配置类

在quartz包下,继续创建一个QuartzConfig类,这是一个SpringBoot的配置类,也是Quartz调度器的配置类,其代码的编写格式基本是固定的,以后需要使用时可直接套用此格式,下面我们写个每10秒触发一次输出当前日期的任务:

package com.codingfire.cloud.stock.quartz;import org.quartz.*;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;// 这个配置类就是在配置已经保存在Spring容器中的调度器Scheduler// 我们需要按下面格式进行配置,才能让Scheduler正常工作@Configurationpublic class QuartzConfig {    // 创建一个JobDetail(工作详情)类对象,保存到Spring容器中,这个类用于封装我们编写的job接口实现类    // @Bean注解标记的方法的返回值会自动保存到Spring容器中(方法名随意)    @Bean    public JobDetail showTime(){        System.out.println("showTime方法运行");        return JobBuilder.newJob(QuartzJob.class)   // 绑定要运行的任务类的反射                .withIdentity("date")               // 设置这个job的名称                .storeDurably()                     //                .build();    }    // 下面要声明触发器,Trigger,触发器决定我们的工作/任务何时触发    @Bean    public Trigger showTimeTrigger(){        System.out.println("showTime触发器运行");        // 定义Cron表达式   每10秒触发一次的定义        CronScheduleBuilder cronScheduleBuilder=                CronScheduleBuilder.cronSchedule("0/10 * * * * ?");        return TriggerBuilder.newTrigger()                .forJob(showTime())        // 绑定JobDetail JobDetail对象已经在Spring容器中                .withIdentity("dateTrigger")       // 定义触发器名称                .withSchedule(cronScheduleBuilder) // 绑定Cron表达式                .build();    }}

测试代码

测试前,如果你实在微服务项目中跟着博主一起操作的,nacos和seata需要先启动,否则会报错,我们的配置文件有配置,若你是新建的项目,则不需要启动这两个服务,只需要确保你的项目能运行起来即可。

启动后,理论上每隔10s会输出一次当前系统时间,我们看看控制台有没有输出:

可以看到是每10s输出一次,你也可以在此处做一些其他的操作,都随你。

storeDurably 需要特别说明下,设置后,如果没有触发器指向此JobDetail,JobDetail也不会被从Spring容器内删除,否则,就会自动从Spring容器内删除。

扩展练习

其实在这个任务中,我们更希望能看到它去调用微服务其他模块的东西,这才是任务调度的真实使用场景,而不是去输出一些东西。下面,我们来尝试调用业务模块来减少库存。

在quartz包下新建一个job类:

package com.codingfire.cloud.stock.quartz;import com.codingfire.cloud.commons.pojo.stock.dto.StockReduceCountDTO;import com.codingfire.cloud.stock.service.IStockService;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.springframework.beans.factory.annotation.Autowired;public class StockJob implements Job {    @Autowired    private IStockService iStockService;    @Override    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {        //库存-10        StockReduceCountDTO stockReduceCountDTO = new StockReduceCountDTO();        stockReduceCountDTO.setCommodityCode("PC100");        stockReduceCountDTO.setReduceCount(-10);        iStockService.reduceCommodityCount(stockReduceCountDTO);    }}

这就是Spring容器的好处,我们直接 @Autowired就可以拿到调用接口,我们在controller里面也是这么用的,在任务调度中也可以当作controller来用,是不是很棒。

这里可以新建一个config类,但我们选择写在输出时间的配置类里,方便大家和前面的代码做对比,添加如下代码:

    @Bean    public JobDetail addStock(){        return JobBuilder.newJob(StockJob.class)                .withIdentity("addStock")                .storeDurably()                .build();    }    @Bean    public Trigger addStockTrigger(){        //从0开始,每1分钟运行一次        CronScheduleBuilder cronScheduleBuilder=                CronScheduleBuilder.cronSchedule("0 0/1 * * * ?");        return TriggerBuilder.newTrigger()                .forJob(addStock())                .withIdentity("addStockTrigger")                .withSchedule(cronScheduleBuilder)                .build();    }

几乎和上面的代码是一样的,只是改了一点参数。那么到这里练习就结束了,如果需要用到dubbo的,和微服务里面一样的,直接用就行,代码就不再贴了,大家可以自己试试。

结语

赶紧关掉这些服务,博主的电脑已经吼起来了。Quart使用起来还是很简单的,也很实用,在项目中使用也很频繁,比如在csdn平台,每周都会有一周小结,都会有一些固定的服务,这些都是通过任务调度自动完成的。看到这里,你对Quart了解了吗,会用了吗?有没有自己上手?咱们下一篇内容再见。

来源地址:https://blog.csdn.net/CodingFire/article/details/129340220

--结束END--

本文标题: Java开发 - Quartz初体验

本文链接: https://lsjlt.com/news/399077.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java开发 - Quartz初体验
    目录​​​​​​​ 前言 Quartz 什么是Quartz Quartz作用 Quartz结构 表达式 案例 Quartz实战 添加依赖 创建Job类 创建配置类 测试代码 扩展练习 结语 前言 在上一篇博客中,我们对单点登录有了初步了...
    99+
    2023-09-07
    Quart 任务调度 scheduling Job JobDetail
  • Java开发 - SpringCache初体验
    前言 早些时候,博主介绍过Redis的使用:Java开发 - Redis初体验,Redie是基于缓存的一项技术,对于Redis,博主此处不再赘述,不了解的可以去看这篇文章,但Redis缓存并不是顶峰,本文要讲的内容就是Redis的辅助工具:...
    99+
    2023-09-05
    Redis SpringCache 缓存 CacheManager Cacheable
  • Java开发 - Elasticsearch初体验
    目录 前言 什么是es? 为什么要使用es? es查询的原理? es需要准备什么?  es基本用法 创建工程 添加依赖 创建操作es的文件 使用ik分词插件 Spring Data 项目中引入Spring Data 添加依赖 添加配置 创建...
    99+
    2023-09-05
    elasticsearch 大数据 搜索引擎 es 微服务
  • Java开发 - Redis初体验
    前言 es我们已经在前文中有所了解,和es有相似功能的是Redis,他们都不是纯粹的数据库。两者使用场景也是存在一定的差异的,本文目的并不重点说明他们之间的差异,但会简要说明,重点还是在对Redis的了解和学习上。学完本篇,你将了解Redi...
    99+
    2023-09-08
    redis 数据库 redis实战 缓存预热 微服务
  • Java开发 - 消息队列之RabbitMQ初体验
    目录 前言 RabbitMQ 什么是RabbitMQ RabbitMQ特点 安装启动 RabbitMQ和Kafka的消息收发区别 RabbitMQ使用案例 添加依赖 添加配置 创建RabbitMQ配置类 RabbitMQ消息的发送 Rab...
    99+
    2023-09-16
    java-rabbitmq rabbitmq java 消息队列 交换机
  • Windows Phone开发工具初体验
    Windows Phone开发工具是一套用于开发Windows Phone应用程序的集成开发环境。以下是我对该工具的初步体验:1. ...
    99+
    2023-09-08
    Windows
  • Java开发 - 单点登录初体验(Spring Security + JWT)
    目录​​​​​​​ 前言 为什么要登录 登录的种类 Cookie-Session Cookie-Session-local storage JWT令牌 几种登陆总结  用户身份认证与授权 创建工程 添加依赖 启动项目 Bcrypt算法的工具...
    99+
    2023-09-02
    登录 JWT Spring Security Token Java登录
  • 在Vue3中使用BabylonJs开发 3D的初体验
    目录开始安装 Vue3安装 BabylonJs创建 Vue 组件: BabylonOne.vue创建 Babylon 类渲染场景修改 CSS 并添加相机和灯光结尾随着前端的发展,在 ...
    99+
    2024-04-02
  • Redis初体验
    Redis是一个速度非常快的非关系型数据库,它不仅性能强劲,而且还具有复制特性以及为解决问题而生的独一无二的数据模型。作为键值型数据库,Redis支持5中数据类型:字符串,列表,集合,Hash散列和有序集合...
    99+
    2024-04-02
  • TiDB 初体验
    ...
    99+
    2024-04-02
  • IronPython初体验
    介绍 在 C# 程序中嵌入 IronPython 得到了很好的支持。在本教程中,我们将展示如何完成这个项目。 首先,我们将展示两个非常基本的例子,说明如何执行一个不导入任何模块的非常简单的脚本。然后,再展示如何执行使用模块的脚本。 在 C...
    99+
    2023-01-30
    初体验 IronPython
  • Python 初体验
    广告:欢迎大家到 路飞学城 学习 Python~ 很喜欢 Python “薪”时代 这个词~所以我们要拥抱 “人工智能”~拥抱 “Python~” 前提:下载 Python,如果是 Mac 电脑会自带 Python。 Hello Worl...
    99+
    2023-01-31
    初体验 Python
  • JetBrainsFleet初体验
    几天前获得了fleet的体验资格。长话短说,今天就来和你一起看看现在的fleet都有啥 先看名字–fleet 什么是fleet? n. 舰队;捕鱼船队;(一国的)全部军舰,海军 看来...
    99+
    2024-04-02
  • 初步体验Oracle
    Oracle 与Mysql 对比: MySQL: 免费;小型企业;仅是数据库;轻 Oracle:收费, 中大型企业;数据库服务(权限,并发,事务,一致性);更适合集群;重 共同点:都属于关系型数据库 RDBMS   非关系型数据库...
    99+
    2014-05-25
    初步体验Oracle
  • Service Mesh 初体验
    前言计算机软件技术发展到现在,软件架构的演进无不朝着让开发者能够更加轻松快捷地构建大型复杂应用的方向发展。容器技术最初是为了解决运行环境的不一致问题而产生的,随着不断地发展,围绕容器技术衍生出来越来越多的新方向。最近几年,云计算领域不断地出...
    99+
    2023-06-05
  • Egret3D之初体验
    Ⅰ,Egret3D官方文档 : https://developer.egret.com/cn/docs/3d/docs/guide/getting-started-introduction/ Ⅱ,安装3D编辑器(以前叫paper , 现在...
    99+
    2023-01-31
    之初 Egret3D
  • java Spring Boot的介绍与初体验
    目录Spring Boot 介绍系统要求构建工具Servlet 容器初体验总结Spring Boot 介绍 Spring Boot用于创建可运行的、独立的、生产级的基于Spring的...
    99+
    2024-04-02
  • nodejs初步体验篇
    前言:写这篇文章的由来:   1.前段时间单位有新项目启动,服务端要做的工作不多也不算麻烦,就是处理一些中间层的服务,而且我们团队里面个个都会JavaScript,领导就决定试试服务器端的JavaScrip...
    99+
    2022-06-04
    nodejs
  • springcloud初体验(真香)
    一、微服务简介 Ⅰ、我对微服务的理解 微服务是软件开发的一种架构方式,由单一的应用小程序构成的小服务;一个软件系统由多个服务组成;在微服务中,服务是细粒度的,协议是轻量级的(部...
    99+
    2024-04-02
  • Oracle 18c安装初体验
    Oracle 18c在万众期待下终于开放下载了,目前提供Linux x86-64、Solaris(SPARC)、Solaris(x86-64)三个平台的下载: 安装包也是水涨船高,Linux版...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作