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

相关推荐
低客的黑调1 小时前
MyBatis-Plus-从 CRUD 到高级特性
java·servlet·tomcat
就像风一样抓不住2 小时前
Java 手机号校验工具类
java
凤山老林2 小时前
26-Java this 关键字
java·开发语言
焦糖玛奇朵婷2 小时前
解锁扭蛋机小程序的五大优势
java·大数据·服务器·前端·小程序
SamDeepThinking2 小时前
别让一个超时的第三方http接口拖垮所有接口
java·后端·架构
YaBingSec3 小时前
玄机靶场:供应链安全-供应链应急-Part2 通关笔记
java·笔记·安全
Gerardisite3 小时前
企微机器人开发指南
java·python·机器人·自动化·企业微信
OtIo TALL3 小时前
Java进阶(ElasticSearch的安装与使用)
java·elasticsearch·jenkins
雨白3 小时前
使用 Kotlin 与 Spring Boot 从零搭建 Web 应用
spring boot·kotlin
一 乐3 小时前
交通感知与车路协同系统|基于springboot + vue交通感知与车路协同系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·交通感知与车路协同系统