下面是 Spring Boot 整合 Quartz 实现定时任务调度 的详细教程,适合用于项目中需要实现定时任务(如自动发送邮件、生成报表、数据同步等)功能的开发者。


🕰️ Spring Boot 整合 Quartz 方法详解


📚 目录

  1. Quartz 简介
  2. 引入依赖(Maven)
  3. 编写 Job(任务)类
  4. 配置 JobDetail 和 Trigger
  5. 配置 Scheduler(调度器)
  6. 使用注解方式定义任务(可选)
  7. Spring Boot 自动装配整合
  8. 实战应用场景举例
  9. Quartz 持久化任务(可选)
  10. 常见问题与建议

1. Quartz 简介

Quartz 是一个功能强大、灵活的 定时任务调度框架,支持:

  • 简单定时(每x秒执行)
  • Cron 表达式
  • 持久化数据库任务记录
  • 集群、高并发调度控制

2. 添加 Maven 依赖

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

如果要启用持久化,还需:

<dependency>
  <groupId>org.quartz-scheduler</groupId>
  <artifactId>quartz</artifactId>
</dependency>

3. 创建 Job 类

public class MyJob implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("执行定时任务:" + new Date());
    }
}

4. 配置 JobDetail 和 Trigger(方式一:配置类方式)

@Configuration
public class QuartzConfig {

    @Bean
    public JobDetail myJobDetail() {
        return JobBuilder.newJob(MyJob.class)
                .withIdentity("myJob")
                .storeDurably()  // 否则任务执行一次后失效
                .build();
    }

    @Bean
    public Trigger myJobTrigger() {
        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(10)  // 每10秒执行
                .repeatForever();

        return TriggerBuilder.newTrigger()
                .forJob(myJobDetail())
                .withIdentity("myTrigger")
                .withSchedule(scheduleBuilder)
                .build();
    }
}

5. 启动调度器(Spring Boot 会自动注入)

只需在配置类中 @Bean 定义任务和触发器,Scheduler 会自动注册运行。


6. 注解方式定义任务(方式二:@DisallowConcurrentExecution)

若你希望通过注解定义任务类,支持并发控制:

@Component
@DisallowConcurrentExecution  // 防止任务并发执行
public class NotifyJob implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("发送通知:" + new Date());
    }
}

7. 动态添加/删除任务(可选增强)

@Autowired
private Scheduler scheduler;

public void addJob(Class<? extends Job> jobClass, String jobName, String groupName, String cron) {
    JobDetail jobDetail = JobBuilder.newJob(jobClass)
        .withIdentity(jobName, groupName)
        .build();

    CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron);

    Trigger trigger = TriggerBuilder.newTrigger()
        .withIdentity(jobName + "Trigger", groupName)
        .withSchedule(cronScheduleBuilder)
        .build();

    scheduler.scheduleJob(jobDetail, trigger);
}

8. 实战应用场景举例

场景描述
每天定时发送报告0 0 9 * * ? 每天上午9点执行
每小时采集接口数据0 0 * * * ? 每小时整点执行
每10分钟同步缓存0 */10 * * * ?

9. 持久化 Quartz 任务(选配)

若需要将任务保存至数据库中(如任务状态、执行历史等):

a. 引入数据库支持依赖:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

b. 配置数据库表结构

使用 Quartz 提供的 SQL 脚本(按数据库选择)

官方 SQL 脚本下载地址

c. 修改 application.yml:

spring:
  quartz:
    job-store-type: jdbc
    jdbc:
      initialize-schema: always
    properties:
      org:
        quartz:
          jobStore:
            class: org.quartz.impl.jdbcjobstore.JobStoreTX
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
            tablePrefix: QRTZ_

10. 常见问题与建议

问题描述解决方案说明
任务只执行一次忘记 .storeDurably() 或触发器未持久
多次执行同一任务方法使用 @DisallowConcurrentExecution
cron 表达式写错使用 cron online editor 检查
不触发任务检查触发器绑定、时间是否在未来
多实例部署任务重复执行使用 Quartz 集群 + 数据库锁机制

✅ 补充:示例 Cron 表达式速查表

Cron 表达式描述
0 0/5 * * * ?每5分钟执行一次
0 0 0 * * ?每天凌晨执行
0 15 10 ? * MON每周一10:15执行

📁 参考资料