0

0

玩转 Spring Boot 集成篇(定时任务框架Quartz)

星夢妙者

星夢妙者

发布时间:2025-07-14 10:18:01

|

1098人浏览过

|

来源于php中文网

原创

在日常项目研发中,定时任务可谓是必不可少的一环,关于 spring boot 如何实现静态定时任务、动态定时任务以及如何开启多线程跑任务,均已在上篇分享过,不再赘述。

虽然 Spring Boot 内置注解方式实现的定时任务,在一定程度上也能解决一定的业务场景问题,但是若做更复杂的动作,例如启停任务、删除任务等等操作,实现起来则稍显复杂,此时便可以通过集成开源任务框架来实现。

常见的定时任务框架有 Quartz、elastic-job、xxl-job等等,本次主要介绍 Spring Boot 集成定时任务第 3 部分:Spirng Boot 集成 Quartz 定时任务框架。

玩转 Spring Boot 集成篇(定时任务框架Quartz)

Quartz 存储方式有两种:MEMORY 和 JDBC。默认是内存形式维护任务信息,意味着服务重启了任务就从头再来,就像喝酒断片了一样;而 JDBC 形式就是能够把任务信息持久化到数据库,虽然服务重启了,依然还能接着来。

Quartz 提供了单机版和集群版,默认就是单机版,接下来逐一分享一波。

Spring Boot 集成 Quartz 的方式也很简单,首先引入封装好的 Quartz 依赖。

代码语言:javascript代码运行次数:0运行复制
<code class="javascript"><!-- 引入 Quartz 依赖--><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-quartz</artifactId></dependency></code>

1. 内存方式存储任务信息

1.1 定义任务类

可以通过实现 Job 接口来定义任务,也可以通过继承 QuartzJobBean 这个抽象类来定义任务,其实 QuartzJobBean 本身也实现了 Job 接口,其本质都是实现 Job 接口来定义任务。

代码语言:javascript代码运行次数:0运行复制
<code class="javascript">import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.springframework.scheduling.quartz.QuartzJobBean;/** * 定义任务 */public class DongAoJob extends QuartzJobBean {    private static final Log logger = LogFactory.getLog(DongAoJob.class);    @Override    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {        logger.info("幼年是盼盼,青年是晶晶,中年是冰墩墩,生活见好逐渐发福");    }}</code>

1.2 定义任务描述及任务触发规则

定义每隔 5 秒执行一次任务,代码如下。

代码语言:javascript代码运行次数:0运行复制
<code class="javascript">import com.example.demo.quartz.task.DongAoJob;import org.quartz.*;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * 定义任务描述和具体的执行时间 */@Configurationpublic class QuartzConfig {    @Bean    public JobDetail jobDetail() {        //指定任务描述具体的实现类        return JobBuilder.newJob(DongAoJob.class)                // 指定任务的名称                .withIdentity("dongAoJob")                // 任务描述                .withDescription("任务描述:用于输出冬奥欢迎语")                // 每次任务执行后进行存储                .storeDurably()                .build();    }        @Bean    public Trigger trigger() {        //创建触发器        return TriggerBuilder.newTrigger()                // 绑定工作任务                .forJob(jobDetail())                // 每隔 5 秒执行一次 job                .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))                .build();    }}</code>

1.3 程序入口 main 函数

代码语言:javascript代码运行次数:0运行复制
<code class="javascript">import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class DemoJobApplication {    public static void main(String[] args) {        SpringApplication.run(DemoJobApplication.class, args);    }}</code>

1.4 运行验证

玩转 Spring Boot 集成篇(定时任务框架Quartz)

通过控制台输出能够看到每 5 秒输出一次信息,达到预期效果。

通过控制台标注 1 的部分能够看到默认采用的是 RAMJobStore,就是将任务相关信息保存在内存里,应用重启后,定时任务信息将会丢失。

2. 数据库方式存储任务信息

2.1 引入依赖

在 pom.xml 文件中加入如下依赖信息。

代码语言:javascript代码运行次数:0运行复制
<code class="javascript"><dependency>    <groupId>com.mchange</groupId>    <artifactId>c3p0</artifactId>    <version>0.9.5.4</version></dependency><!-- MySQL 驱动 --><dependency>    <groupId>mysql</groupId>    <artifactId>mysql-connector-java</artifactId></dependency></code>

2.2 添加 Quartz 配置信息

在 application.properties 文件中加入 Quartz 相关配置。

代码语言:javascript代码运行次数:0运行复制
<code class="javascript"># 将 Quartz 持久化方式修改为 jdbcspring.quartz.job-store-type=jdbc# 实例名称(默认为quartzScheduler)spring.quartz.properties.org.quartz.scheduler.instanceName=SC_Scheduler# 实例节点 ID 自动生成spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO# 修改存储内容使用的类spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX# 数据源信息spring.quartz.properties.org.quartz.jobStore.dataSource=quartz_jobsspring.quartz.properties.org.quartz.dataSource.quartz_jobs.driver=com.mysql.cj.jdbc.Driverspring.quartz.properties.org.quartz.dataSource.quartz_jobs.URL=jdbc:mysql://127.0.0.1:3306/quartz_jobs?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8spring.quartz.properties.org.quartz.dataSource.quartz_jobs.user=rootspring.quartz.properties.org.quartz.dataSource.quartz_jobs.password=123456</code>

2.3 初始化 Quartz 数据表信息

下载 Quartz 发布包,下载完成后,解压缩进入 quartz-2.2.3/docs/dbTables 目录,找到匹配数据库的 SQL 文件。

代码语言:javascript代码运行次数:0运行复制
<code class="javascript">下载地址:https://www.quartz-scheduler.org/downloads/files/quartz-2.2.3-distribution.tar.gz</code>

为了方便演示,单独创建 quartz_jobs 数据库。

代码语言:javascript代码运行次数:0运行复制
<code class="javascript">create database quartz_jobs default charset utf8;use quartz_jobs;</code>

然后在数据库中执行 tables-mysql.sql 初始化脚本,脚本内容如下(来源于官网压缩包),先别细究每个表的意义,用起来才是硬道理。

代码语言:javascript代码运行次数:0运行复制
<code class="javascript">DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;DROP TABLE IF EXISTS QRTZ_LOCKS;DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;DROP TABLE IF EXISTS QRTZ_TRIGGERS;DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;DROP TABLE IF EXISTS QRTZ_CALENDARS;CREATE TABLE QRTZ_JOB_DETAILS  (    SCHED_NAME VARCHAR(120) NOT NULL,    JOB_NAME  VARCHAR(200) NOT NULL,    JOB_GROUP VARCHAR(200) NOT NULL,    DESCRIPTION VARCHAR(250) NULL,    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,    IS_DURABLE VARCHAR(1) NOT NULL,    IS_NONCONCURRENT VARCHAR(1) NOT NULL,    IS_UPDATE_DATA VARCHAR(1) NOT NULL,    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,    JOB_DATA BLOB NULL,    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP));CREATE TABLE QRTZ_TRIGGERS  (    SCHED_NAME VARCHAR(120) NOT NULL,    TRIGGER_NAME VARCHAR(200) NOT NULL,    TRIGGER_GROUP VARCHAR(200) NOT NULL,    JOB_NAME  VARCHAR(200) NOT NULL,    JOB_GROUP VARCHAR(200) NOT NULL,    DESCRIPTION VARCHAR(250) NULL,    NEXT_FIRE_TIME BIGINT(13) NULL,    PREV_FIRE_TIME BIGINT(13) NULL,    PRIORITY INTEGER NULL,    TRIGGER_STATE VARCHAR(16) NOT NULL,    TRIGGER_TYPE VARCHAR(8) NOT NULL,    START_TIME BIGINT(13) NOT NULL,    END_TIME BIGINT(13) NULL,    CALENDAR_NAME VARCHAR(200) NULL,    MISFIRE_INSTR SMALLINT(2) NULL,    JOB_DATA BLOB NULL,    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)        REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP));CREATE TABLE QRTZ_SIMPLE_TRIGGERS  (    SCHED_NAME VARCHAR(120) NOT NULL,    TRIGGER_NAME VARCHAR(200) NOT NULL,    TRIGGER_GROUP VARCHAR(200) NOT NULL,    REPEAT_COUNT BIGINT(7) NOT NULL,    REPEAT_INTERVAL BIGINT(12) NOT NULL,    TIMES_TRIGGERED BIGINT(10) NOT NULL,    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP));CREATE TABLE QRTZ_CRON_TRIGGERS  (    SCHED_NAME VARCHAR(120) NOT NULL,    TRIGGER_NAME VARCHAR(200) NOT NULL,    TRIGGER_GROUP VARCHAR(200) NOT NULL,    CRON_EXPRESSION VARCHAR(200) NOT NULL,    TIME_ZONE_ID VARCHAR(80),    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP));CREATE TABLE QRTZ_SIMPROP_TRIGGERS  (              SCHED_NAME VARCHAR(120) NOT NULL,    TRIGGER_NAME VARCHAR(200) NOT NULL,    TRIGGER_GROUP VARCHAR(200) NOT NULL,    STR_PROP_1 VARCHAR(512) NULL,    STR_PROP_2 VARCHAR(512) NULL,    STR_PROP_3 VARCHAR(512) NULL,    INT_PROP_1 INT NULL,    INT_PROP_2 INT NULL,    LONG_PROP_1 BIGINT NULL,    LONG_PROP_2 BIGINT NULL,    DEC_PROP_1 NUMERIC(13,4) NULL,    DEC_PROP_2 NUMERIC(13,4) NULL,    BOOL_PROP_1 VARCHAR(1) NULL,    BOOL_PROP_2 VARCHAR(1) NULL,    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)     REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP));CREATE TABLE QRTZ_BLOB_TRIGGERS  (    SCHED_NAME VARCHAR(120) NOT NULL,    TRIGGER_NAME VARCHAR(200) NOT NULL,    TRIGGER_GROUP VARCHAR(200) NOT NULL,    BLOB_DATA BLOB NULL,    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP));CREATE TABLE QRTZ_CALENDARS  (    SCHED_NAME VARCHAR(120) NOT NULL,    CALENDAR_NAME  VARCHAR(200) NOT NULL,    CALENDAR BLOB NOT NULL,    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME));CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS  (    SCHED_NAME VARCHAR(120) NOT NULL,    TRIGGER_GROUP  VARCHAR(200) NOT NULL,     PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP));CREATE TABLE QRTZ_FIRED_TRIGGERS  (    SCHED_NAME VARCHAR(120) NOT NULL,    ENTRY_ID VARCHAR(95) NOT NULL,    TRIGGER_NAME VARCHAR(200) NOT NULL,    TRIGGER_GROUP VARCHAR(200) NOT NULL,    INSTANCE_NAME VARCHAR(200) NOT NULL,    FIRED_TIME BIGINT(13) NOT NULL,    SCHED_TIME BIGINT(13) NOT NULL,    PRIORITY INTEGER NOT NULL,    STATE VARCHAR(16) NOT NULL,    JOB_NAME VARCHAR(200) NULL,    JOB_GROUP VARCHAR(200) NULL,    IS_NONCONCURRENT VARCHAR(1) NULL,    REQUESTS_RECOVERY VARCHAR(1) NULL,    PRIMARY KEY (SCHED_NAME,ENTRY_ID));CREATE TABLE QRTZ_SCHEDULER_STATE  (    SCHED_NAME VARCHAR(120) NOT NULL,    INSTANCE_NAME VARCHAR(200) NOT NULL,    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,    CHECKIN_INTERVAL BIGINT(13) NOT NULL,    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME));CREATE TABLE QRTZ_LOCKS  (    SCHED_NAME VARCHAR(120) NOT NULL,    LOCK_NAME  VARCHAR(40) NOT NULL,     PRIMARY KEY (SCHED_NAME,LOCK_NAME));commit;</code>

2.4 运行验证

代码无需任何变动,直接运行 main 函数,控制台输出如下:

玩转 Spring Boot 集成篇(定时任务框架Quartz)

通过控制台输出发现任务正常跑起来,而且任务存储的方式变为了 jdbcjobstore.JobStoreTx,此时数据库表中也有任务信息插入了。

GPTPLUS
GPTPLUS

GPTPLUS, 由GPT-4和GPT-3.5支持,为您的写作、翻译、代码分析和问答需求提供最准确、有效的AI反馈。

下载
玩转 Spring Boot 集成篇(定时任务框架Quartz)

至此,Spring Boot 集成 Quartz 的两种存储任务方式就完事儿了,其实很简单,稍显复杂的多是 Quartz 相关的持久化依赖的 SQL 及配置信息。

但是,在某些业务场景下要求任务必须高可用、可扩展,那么单台服务器不能满足业务需求,这时就需要开启 Quartz 分布式定时任务啦。

3. 分布式任务支持

3.1 开启集群配置

在 application.properties 文件中,加入 Quartz 集群的配置信息。

代码语言:javascript代码运行次数:0运行复制
<code class="javascript"># 开启集群,多个 Quartz 实例使用同一组数据库表spring.quartz.properties.org.quartz.jobStore.isClustered=true</code>

注意 Quartz 使用同一组数据库表作集群时,只需要配置相同的 instanceName 实例名称就可以,例如本次都用 SC_Scheduler。

代码语言:javascript代码运行次数:0运行复制
<code class="javascript"> spring.quartz.properties.org.quartz.scheduler.instanceName=SC_Scheduler</code>

3.2 运行验证

为了方便启动多实例验证,把服务启动的端口进行随机生成,application.properties 文件加入配置如下。

代码语言:javascript代码运行次数:0运行复制
<code class="javascript">server.port=${random.int[10000,19999]}</code>

直接运行 main 函数,启动实例 1;再次运行 main 函数,启动实例2(如果 IDEA 不让重复运行,那就重新复制一个启动类,再运行)。

玩转 Spring Boot 集成篇(定时任务框架Quartz)

通过红色圈住部分 is clustered,显然已是开启了集群。若关闭其中一个正在跑任务的节点,观察另一个节点是否会自动检测继续执行任务呢?

停掉节点 1:

玩转 Spring Boot 集成篇(定时任务框架Quartz)

节点 2 继续接着执行任务:

玩转 Spring Boot 集成篇(定时任务框架Quartz)

至此,Spring Boot 集成 Quartz 可以接近尾声了。

不过稍显不甘心呢,因为回头看代码,会发现 QuartzConfig 中的 job 和 trigger 都是硬编码方式完成的。

玩转 Spring Boot 集成篇(定时任务框架Quartz)

这样肯定无法管理任务的状态,无法做到扩展,更达不到 Spring Boot 的思想让程序员更专注业务开发,所以仍有改进的空间,仍存很多疑问。

疑问:是否可以通过 API 动态创建任务呢?

疑问:是否可以通过 API 编辑任务的执行时间呢?

疑问:是否可以通过 API 暂停/恢复任务呢?

疑问:是否可以通过 API 删除任务呢?

疑问:是否可以 ... ...

此时,可以这么回答:of course.Im very sure. 老鼠拉木锨——大头在后面呢,不过限于自定义代码较多,单独放一代码篇去分享。

4. 例行回顾

本文是 Spring Boot 项目集成 Quartz 定时任务框架讲解,主要分享了如下部分:

默认内存方式存储任务信息;数据库方式任务信息;分布式任务支持

玩转 Spring Boot 集成 Quartz 定时任务就写到这里,下次一起编码实现 Quartz 任务的动态管理。

历史系列文章:

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

1090

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

340

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

380

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2028

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

379

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

1580

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

585

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

438

2024.04.29

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

4

2026.03.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 2.5万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 844人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号