Files
blog-press/docs/Web/SpringBoot/SpringBoot-Quartz.md

120 lines
4.3 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: SpringBoot Quarzt简介和使用
date: 2026-06-08
---
# 一、基本概念
  Quartz 是 Java 生态最主流的企业级作业调度框架支持简单间隔触发、Cron 表达式、持久化到数据库、集群部署。
- Job任务 — 实现 execute()方法,写你要执行的业务逻辑
- Trigger触发器 — 定义"什么时候执行",常用 SimpleTrigger固定间隔和 CronTriggerCron 表达式)
- Scheduler调度器 — 把 Job + Trigger 绑定,负责启动和停止调度
# 二、原理
  Job相当于员工只知道干活Trigger 相当于排班表决定什么时候干活Scheduler 相当于老板,统一管理 Job 和 Trigger。
  Quartz内部有一个核心线程 QuartzSchedulerThread会不停的检查哪个员工需要在啥时候干活但并不是按照固定间隔轮询的方式而是计算出最近一次 Trigger 的触发时间,通过 wait()精确等待,当等待结束后,调度线程会唤醒线程池中的工作线程,执行到点的 Job。如果当前没有任何 Trigger了默认最多等待 30 秒,然后再重新扫描​。如果此时有新增/修改/删除任务了,调度线程会被 notifyAll()立即唤醒,重新计算最近的触发时间。
# 三、安装
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
```
&emsp;&emsp;持久化:
```yml
spring:
quartz:
job-store-type: jdbc
```
&emsp;&emsp;启用后会在数据库自动建表。
# 四、使用
## 4.1 定义Job
```java
@Component
@DisallowConcurrentExecution // 防止同一 Job 并发执行
public class QuartzJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) {
// 获取任务内容
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
// TODO 根据任务内容执行任务
}
}
```
## 4.2 定义Trigger
```java
@Component
public class QuartzUtils {
public static JobDetail buildJobDetail(Task task, JobKey jobKey) {
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("id", task.getId());
jobDataMap.put("type", task.getType());
jobDataMap.put("content", task.getContent());
return JobBuilder.newJob(QuartzJob.class)
.withIdentity(jobKey) // 使用 id 作为唯一标识
.usingJobData(jobDataMap)
.build();
}
public static Trigger buildTrigger(Task task, JobKey jobKey) {
Trigger trigger;
// 判断任务类型Cron 任务或者一次性任务
if (task.getCronExpression() != null && !task.getCronExpression().isEmpty()) {
// 定时任务:使用 Cron 表达式
trigger = TriggerBuilder.newTrigger()
.withIdentity(jobKey.getName() + "Trigger")
.withSchedule(CronScheduleBuilder.cronSchedule(task.getCronExpression()))
.forJob(jobKey)
.build();
} else if (task.getExecuteTime() != null) {
// 一次性任务:使用 executeTime
trigger = TriggerBuilder.newTrigger()
.withIdentity(jobKey.getName() + "Trigger")
.startAt(task.getExecuteTime())
.forJob(jobKey)
.build();
} else {
// 如果没有 Cron 表达式和 executeTime任务不能调度抛出异常
throw new CustomException("任务没有有效的 Cron 表达式或执行时间");
}
return trigger;
}
}
```
::: tip
这里的Task可以根据实际情况定义:
```java
@Data
public class Task {
private Long id;
private String type;
private String content;
private Date executeTime;
private String cronExpression;
}
```
:::
## 4.3 执行Scheduler
```java
@Resource
private Scheduler scheduler;
// 新增/更新
JobKey jobKey = new JobKey(task.getId().toString());
scheduler.scheduleJob(QuartzUtils.buildJobDetail(task, jobKey), QuartzUtils.buildTrigger(task, jobKey));
// 更新
scheduler.rescheduleJob(QuartzUtils.buildJobDetail(task, jobKey), QuartzUtils.buildTrigger(task, jobKey));
// 删除
scheduler.deleteJob(jobKey);
```