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 秒打印一行。

相关推荐
唐不是营养物质2 小时前
无头浏览器chromedriver使用(目前不支持国产操作系统)
java·pdf
zhishidi3 小时前
使用python给pdf文档自动添加目录书签
java·python·pdf
WiChP11 小时前
【V0.1B5】从零开始的2D游戏引擎开发之路
java·服务器·数据库
cch891811 小时前
汇编与Java:底层与高层的编程对决
java·开发语言·汇编
荒川之神12 小时前
拉链表概念与基本设计
java·开发语言·数据库
cch891812 小时前
汇编与Go:底层到高层的编程差异
java·汇编·golang
chushiyunen12 小时前
python中的@Property和@Setter
java·开发语言·python
禾小西12 小时前
Java中使用正则表达式核心解析
java·python·正则表达式