Spring boot整合quartz方法

目录

1.定时任务

1.quartz说明

2.Quartz提供了不同的数据存储策略以管理作业调度信息:

1.Quartz引入依赖

2.开发定时任务

(1)更新定时任务

(2)停止定时任务

(3)唤醒定时任务

(4)删除定时任务


1.定时任务

定时任务的实现途径多种多样,以下是一些不同的方法:

1. 在应用程序的启动类中引入`@EnableScheduling`注解,以此激活定时任务的功能。随后,可以利用注解`@Scheduled`,配合Cron表达式(例如`@Scheduled(cron = "0/1 * * * * ")`)来定义任务的执行频率,同时确保这些任务被注册为Spring管理的Bean。

2. 采用外部任务调度框架,例如xxl-job或elastic-Job,这些框架提供了额外的功能和灵活性,以满足更复杂的调度需求。

3. 使用Quartz作为底层实现,许多第三方框架实际上都是基于Quartz构建的,它们提供了更高级的调度功能和更好的集成支持。

1.quartz说明

Quartz是一个纯Java编写的工作调度框架,它包含以下核心组件:

1. 调度器(Scheduler): ? ?这是Quartz中负责调度作业的核心组件。它通过与触发器(Trigger)和作业详情(JobDetail)的交互来控制作业的执行。调度器作为一个容器,保存了作业和触发器,它们在调度器中都有唯一的组和名称,这些标识符用于调度器内部查找和识别特定的作业或触发器。触发器和作业详情的组名和名称必须是唯一的,尽管它们可以相同,因为它们属于不同的类别。

2. 触发器(Trigger): ? ?在Quartz中,触发器定义了作业执行的时间规则。它有两个主要的子类型:SimpleTrigger和CronTrigger,分别用于简单的周期性调度和复杂的时间表调度。

3. 作业详情(JobDetail): ? ?这包含了Quartz中作业的具体信息,包括作业的唯一标识和要执行的任务。作业详情还允许通过JobDataMap传递额外的数据给作业。

4. 作业(Job): ? ?这是Quartz中定义作业具体执行逻辑的接口。实现这个接口的类包含了作业执行的核心代码。

5. 作业构建器(JobBuilder): ? ?这是一个工具类,用于构建作业实例,并定义作业的属性,如名称和组名。构建的实例将代表一个实际要执行的作业。

6. 触发器构建器(TriggerBuilder): ? ?这个工具类用于创建触发器实例,定义触发器的属性和行为。

7. 监听器(Listener): ? ?Quartz提供了多种监听器,包括作业监听器(JobListener)、触发器监听器(TriggerListener)和调度器监听器(SchedulerListener),它们用于监控作业、触发器和调度器的事件和状态变化。

2.Quartz提供了不同的数据存储策略以管理作业调度信息:

内存存储(RAMJobStore): Quartz默认使用内存作为存储介质,这种方式因其直接在内存中操作而具有极高的性能。然而,这种存储方式不具备数据持久性,一旦应用程序崩溃或需要重新部署,所有存储的调度信息将无法保留。

数据库存储: 通过将调度信息存储在数据库中,Quartz可以实现单实例或集群部署,便于对大量作业进行集中管理和动态控制,如暂停、停止或修改作业。即使在服务器关闭或重启后,作业的调度信息也能得以保留。不过,这种存储方式的性能会受到数据库连接速度的影响。

1.Quartz引入依赖

首先,要在Springboot项目可以直接引入下面依赖

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

如果是非Springboot项目,可以引入以下依赖

复制代码
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.3</version>
</dependency>

2.开发定时任务

首先,我们需要创建一个类

复制代码
package com.example.yin.taskjob;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

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

接着,我们需要为他设置接口。

复制代码
public interface QuartzService {
    public R addCronJob(String jobName, String cron, String jobClassName, String triggerName);
    public R updateCronJob(String jobName,String cron, String jobClassName);
    public R pauseCronJob(String jobName, String triggerName);
    public R resumeCronJob(String jobName, String triggerName);
    public R deleteCronJob(String jobName, String jobGroup, String triggerName, String triggerGroup);
}

接口中的方法用于添加、更新、暂停、恢复和删除基于Cron表达式的定时作业;返回类型为R的对象,R可能是一个自定义的响应类,用于封装方法执行的结果,请根据自己项目来修改!

然后,定时任务继承TaskJob,并实现其方法

复制代码
@Service
public class QuartServiceImpl implements QuartzService {
    @Autowired
    private Scheduler scheduler;
    private static final String DEFAULT_JOB_GROUP = "default_job_group";

    private static final String DEFAULT_TRIGGER_GROUP = "default_trigger_group";

    private static final String TRIGGER_PRE = "Trigger_";
    @Override
    public R addCronJob(String jobName, String cron, String jobClassName, String triggerName) {
        try{
            JobKey jobKey = JobKey.jobKey(jobName, DEFAULT_JOB_GROUP);
            if (scheduler.checkExists(jobKey)){
                return R.fail("【添加定时任务】该作业已存在");
            }
            //构建job
            JobDetail job = (JobDetail) JobBuilder
                    .newJob((Class<? extends Job>) Class.forName(jobClassName))
                    .withIdentity(jobKey)
                    .build();
            //Cron表达式定时构造器
            CronScheduleBuilder cronSchedule = CronScheduleBuilder.cronSchedule(cron);
            //构建Trigger
            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity(TriggerKey.triggerKey(TRIGGER_PRE + triggerName, DEFAULT_TRIGGER_GROUP))
                    .withSchedule(cronSchedule)
                    .build();
            //启动调度
            scheduler.scheduleJob(job, trigger);
            scheduler.start();
        }catch (Exception e){
            return R.fail("创建定任务失败,原因是:" + e.getMessage());
        }
        return  R.success("创建定时任务成功!", jobName + ",任务表达式:" + cron);
    }

这个方法提供了一个完整的流程,用于将一个新的Cron作业添加到Quartz调度器中,并确保作业按照指定的Cron表达式执行。通过动态加载作业类和构建触发器,这个方法提供了灵活的作业调度能力。

然后,让我们创建一个控制类

复制代码
@RestController
@RequestMapping("/quartz")
public class QuartzController {
    @Autowired
    private QuartzService quartzService;

    @PostMapping("createJob")
    public R createJob(@RequestBody JobInfo jobInfo) {
        return quartzService.addCronJob(jobInfo.getJobName(),jobInfo.getCron(),jobInfo.getJobClassName(), jobInfo.getTriggerName());
    }

到这里,其实一个简单的Quartz定时任务已经完成了

我们可以去swagger-ui测试效果(不会使用swagger-ui的小伙伴,可以使用其他接口软件)

测试接口推荐

这里推荐几个接口地址,供小伙伴自行选择

1. Apifox - API 文档、调试、Mock、测试一体化协作平台。拥有接口文档管理、接口调试、Mock、自动化测试等功能,接口开发、测试、联调效率,提升 10 倍。最好用的接口文档管理工具,接口自动化测试工具。[这里是图片001]https://apifox.com/2.Postman: The World's Leading API Platform | Sign Up for Free。支持各种 HTTP 请求方法,并且提供了强大的测试脚本功能,你可以为每个请求编写测试用例,自动化你的 API 测试过程。(建议科学上网使用)

3.The Collaborative API Development Platform - Insomnia。是一个轻量级的 REST 客户端,界面干净利落,使用起来非常直观,虽然 Insomnia 主要聚焦在 API 测试上,但它也提供了基本的文档生成功能。

spring boot项目控制台会显示此效果

最后,我们可以在实现方法中添加更新定时任务,停止定时任务,唤醒定时任务,删除定时任务

(1)更新定时任务
复制代码
@Override
    public R updateCronJob(String jobName, String cron, String triggerName) {
        try{
            TriggerKey triggerKey = TriggerKey.triggerKey(TRIGGER_PRE + triggerName, DEFAULT_TRIGGER_GROUP);
            CronScheduleBuilder cronSchedule = CronScheduleBuilder.cronSchedule(cron);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronSchedule).build();
            scheduler.rescheduleJob(triggerKey, trigger);
            return R.success("更新定时任务成功!");
        }catch (Exception e){
            return R.fail("更新定时任务失败,原因为:" + e.getMessage());
        }
    }
(2)停止定时任务
复制代码
@Override
    public R pauseCronJob(String jobName, String triggerName) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(TRIGGER_PRE + triggerName, DEFAULT_TRIGGER_GROUP);
            JobKey jobKey = JobKey.jobKey(jobName, DEFAULT_JOB_GROUP);

            // 检查作业和触发器是否存在
            if (!scheduler.checkExists(jobKey) || !scheduler.checkExists(triggerKey)) {
                return R.fail("作业或触发器不存在");
            }

            // 暂停触发器
            scheduler.pauseTrigger(triggerKey);
            return R.success("暂停定时任务成功!");
        } catch (Exception e) {
            return R.fail("暂停定时任务失败,原因是:" + e.getMessage());
        }

    }
(3)唤醒定时任务
复制代码
 @Override
    public R resumeCronJob(String jobName, String triggerName) {
        try {
            // 构建触发器key
            TriggerKey triggerKey = TriggerKey.triggerKey(TRIGGER_PRE + triggerName, DEFAULT_TRIGGER_GROUP);
            // 恢复触发器
            scheduler.resumeTrigger(triggerKey);
            return R.success("恢复定时任务成功!");
        } catch (Exception e) {
            return R.fail("恢复定时任务失败,原因是:" + e.getMessage());
        }
    }
(4)删除定时任务
复制代码
@Override
    public R deleteCronJob(String jobName, String jobGroup, String triggerName, String triggerGroup) {
        try {
            JobKey jobKey = JobKey.jobKey(jobName,  DEFAULT_JOB_GROUP);
            TriggerKey triggerKey = TriggerKey.triggerKey(TRIGGER_PRE + triggerName, DEFAULT_TRIGGER_GROUP);

            if (!scheduler.checkExists(jobKey) ||!scheduler.checkExists(triggerKey)) {
                return R.fail("【删除定时任务】作业或触发器不存在");
            }

            scheduler.unscheduleJob(triggerKey);
            scheduler.deleteJob(jobKey);

            return R.success("删除定时任务成功!", jobName);
        } catch (Exception e) {
            return R.fail("删除定时任务失败,原因为:" + e.getMessage());
        }
        }

在添加完所有方法后,将相应的控制类补全,swagger-ui就会呈现所有接口

以下是剩余控制类方法

复制代码
@PostMapping("updateJob")
    public R updateJob(@RequestBody JobInfo jobInfo) {
        return quartzService.updateCronJob(jobInfo.getJobName(), jobInfo.getCron(), jobInfo.getTriggerName());
    }
    @PostMapping("pauseJob")
    public R pauseJob(@RequestBody JobInfo jobInfo) {
        return quartzService.pauseCronJob(jobInfo.getJobName(), jobInfo.getTriggerName());
    }

    @PostMapping("resumeJob")
    public R resumeJob(@RequestBody JobInfo jobInfo) {
        return quartzService.resumeCronJob(jobInfo.getJobName(), jobInfo.getTriggerName());
    }

    @DeleteMapping("deleteJob")
    public R deleteJob(@RequestBody JobInfo jobInfo) {
        return quartzService.deleteCronJob(jobInfo.getJobName(), jobInfo.getJobGroup(), jobInfo.getTriggerName(), jobInfo.getTriggerGroup());
    }
}

我们可以到swagger-ui去查看接口是否齐全

可以看到,我们的实现接口是正确显示的,到这里,Spring boot整合Quartz项目就算完成了。

相关推荐
侠客行031714 小时前
Mybatis连接池实现及池化模式
java·mybatis·源码阅读
蛇皮划水怪14 小时前
深入浅出LangChain4J
java·langchain·llm
子兮曰14 小时前
OpenClaw入门:从零开始搭建你的私有化AI助手
前端·架构·github
吴仰晖14 小时前
使用github copliot chat的源码学习之Chromium Compositor
前端
1024小神14 小时前
github发布pages的几种状态记录
前端
老毛肚16 小时前
MyBatis体系结构与工作原理 上篇
java·mybatis
风流倜傥唐伯虎16 小时前
Spring Boot Jar包生产级启停脚本
java·运维·spring boot
不像程序员的程序媛16 小时前
Nginx日志切分
服务器·前端·nginx
Yvonne爱编码17 小时前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python
Re.不晚17 小时前
JAVA进阶之路——无奖问答挑战1
java·开发语言