120 lines
4.3 KiB
Markdown
120 lines
4.3 KiB
Markdown
---
|
||
title: SpringBoot Quarzt简介和使用
|
||
date: 2026-06-08
|
||
---
|
||
|
||
# 一、基本概念
|
||
  Quartz 是 Java 生态最主流的企业级作业调度框架,支持简单间隔触发、Cron 表达式、持久化到数据库、集群部署。
|
||
- Job(任务) — 实现 execute()方法,写你要执行的业务逻辑
|
||
- Trigger(触发器) — 定义"什么时候执行",常用 SimpleTrigger(固定间隔)和 CronTrigger(Cron 表达式)
|
||
- 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>
|
||
```
|
||
|
||
  持久化:
|
||
```yml
|
||
spring:
|
||
quartz:
|
||
job-store-type: jdbc
|
||
```
|
||
|
||
  启用后会在数据库自动建表。
|
||
|
||
# 四、使用
|
||
## 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);
|
||
``` |