Quartz 入门指南(二)Spring Boot + Quartz 示例

原理篇:Quartz 入门指南(一)原理篇

1. 添加 Maven 依赖

java 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

spring-boot-starter-quartz ‌ 是 Spring Boot 提供的一个用于集成 ‌Quartz 调度框架 ‌ 的启动器(Starter),旨在简化在 Spring Boot 应用中配置和使用 Quartz 定时任务的过程。引入该依赖后,Spring Boot 会自动完成 Quartz 的基础配置,如自动配置了 Quartz 的 SchedulerFactoryBeanJobStore(默认内存存储)以及必要的线程池等。

2. 实现Job类

java 复制代码
package com.example.QuartzDemo;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 示例 Job:打印当前时间 + 从 JobDataMap 中读取的参数
 */
@Component  // 让 Spring 管理这个 Job 实例(但 Quartz 默认会反射创建新实例,所以 @Component 主要便于注入依赖)
public class SampleJob implements Job {

    private static final Logger log = LoggerFactory.getLogger(SampleJob.class);

    /**
     * Quartz 调用的执行方法,每次触发都会创建一个新的 SampleJob 实例并调用此方法
     * @param context 包含了 JobDetail、Trigger、JobDataMap 等运行时信息
     */
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        // 1. 从 JobDataMap 中获取参数(可在定义 JobDetail 或 Trigger 时放入)
        String message = (String) context.getJobDetail().getJobDataMap().get("myMessage");
        int repeatCount = context.getJobDetail().getJobDataMap().getInt("repeatCount");

        // 2. 业务逻辑:打印带时间戳的日志
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        log.info("【{}】执行任务,参数 message={}, repeatCount={}",
                LocalDateTime.now().format(formatter), message, repeatCount);
    }
}

JobExecutionContext:携带了当前任务的所有上下文,包括 JobDetailTrigger 以及合并后的 JobDataMap

JobExecutionContext 的核心作用
  1. 提供 JobDetail 和 Trigger 的访问入口: Job 可以通过它获取当前执行的 JobDetail(任务定义)和 Trigger(触发器),从而知道"做什么"和"为什么做"。

  2. 获取合并后的 JobDataMap: JobDetailTrigger 都可能携带 JobDataMap 数据,JobExecutionContext 提供了一个 合并后的视图(Trigger 中的同名参数会覆盖 JobDetail 中的)。这是 Job 获取运行时参数的标准方式。

  3. 获取调度器(Scheduler)实例: 如果 Job 中需要动态操作调度器(如添加、暂停、删除其他任务),可以通过 getScheduler() 获得 Scheduler 对象。

  4. **获取运行时环境信息:**例如:实际触发时间、计划触发时间、重试次数、FireTime 等,便于任务内做逻辑判断(如检测是否错失触发)。

  5. 存储临时数据(结果、中间状态): 通过 put(Object key, Object value) 可以存储临时数据,这些数据只在当前 Job 执行过程中有效(不会持久化)。也可以用于 JobTriggerListener 之间的通信。

  6. 检测任务是否被中断: 如果任务支持可中断,可以通过 isInterrupted() 检查是否收到中断信号。

3. 配置 JobDetail 和 Trigger(使用 @Bean 定义)

java 复制代码
package com.example.QuartzDemo;

import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Quartz 配置类:定义 JobDetail 和 Trigger 的 Bean
 */
@Configuration
public class QuartzConfig {

    /**
     * 1. 定义 JobDetail
     *    - 使用 JobBuilder.newJob() 指定 Job 类(必须是 Job 的实现类)
     *    - withIdentity() 设置任务唯一标识(名称和组)
     *    - usingJobData() 向 JobDataMap 中放入静态参数
     *    - storeDurably() 设置持久性:即使没有关联 Trigger 也保留该 JobDetail
     */
    @Bean
    public JobDetail sampleJobDetail() {
        return JobBuilder.newJob(SampleJob.class)          // 关联 SampleJob 类
                .withIdentity("sampleJob", "group1")       // 任务标识
                .usingJobData("myMessage", "Hello Quartz") // 向 JobDataMap 存入参数
                .usingJobData("repeatCount", 3)            // 另一个参数
                .storeDurably()                            // 持久化存储(不必须,但建议)
                .build();
    }

    /**
     * 2. 定义 Trigger(触发器)
     *    - 使用 TriggerBuilder 关联上面定义好的 JobDetail
     *    - withIdentity() 设置触发器标识
     *    - withSchedule() 定义调度规则(这里使用 CronScheduleBuilder 的 cron 表达式)
     *    - 可选:startNow() 立即开始,也可使用 startAt() 指定未来时间
     */
    @Bean
    public Trigger sampleJobTrigger() {
        return TriggerBuilder.newTrigger()
                .forJob(sampleJobDetail())                // 关联哪个 JobDetail
                .withIdentity("sampleTrigger", "group1")  // 触发器标识
                .startNow()                               // 创建后立即生效
                .withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?")) // 每 10 秒执行一次
                .build();
    }
}

4. 运行效果

启动应用后,可以看到控制台每 10 秒打印一行。

相关推荐
许彰午4 小时前
14_Java泛型完全指南
java·windows·python
智慧物业老杨4 小时前
司法绿色通道下的物业纠纷数智化解决方案——基于“三优先“机制的全流程技术落地实践
java·django
2601_961194025 小时前
2026初级会计实务公式总结大全|计算题公式手册PDF
java·spring·eclipse·pdf·tomcat·hibernate
做个文艺程序员5 小时前
第1篇:K8s 核心概念精讲:Pod、Deployment、Service 与 Namespace——Java 开发者快速上手指南
java·云原生·容器·kubernetes·容器编排
小欣加油7 小时前
leetcode3751 范围内总波动值I
java·数据结构·c++·算法·leetcode
闪电悠米7 小时前
黑马点评-Redisson-01_why_redisson
java·服务器·网络·数据库·缓存·wpf
星轨zb7 小时前
LangChain4j 集成 Spring Boot:会话记忆 NPE 的根源与 ChatMemoryProvider 正确配置
java·spring boot·后端·langchain4j
JAVA9657 小时前
JAVA面试-并发篇 05-并发包AQS队列实现原理是什么
java·开发语言·面试
JAVA面经实录9177 小时前
RocketMQ全套学习知识手册
java·kafka·rabbitmq·rocketmq
混凝土拌意大利面7 小时前
TG-BOOT springboot 功能集散开发框架(AI 协作友好)
人工智能·spring boot·后端