首页 > 其他分享 >SpringBoot整合Quartz实现动态定时任务

SpringBoot整合Quartz实现动态定时任务

时间:2024-02-21 16:05:08浏览次数:24  
标签:Quartz SpringBoot 任务 quartz scheduler new import 定时 String

1、增加依赖

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

<!-- json 工具 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>xxx</version>
</dependency>

 

2、application.yml 文件配置

 
# 引入 数据库的相关配置
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://local:3306/springboot?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true
    username: root
    password: abc123
  #配置 quartz
  quartz:
    #初始化数据库脚本路径,默认使用classpath:org/quartz/impl/jdbcjobstore/tables_@@platform@@.sql路径下的脚本
    #注意,放置的是 spring.quartz 下面
    #持久化到数据库方式
    job-store-type: jdbc
    # 初始化Quartz表结构,项目第一次启动配置程always,然后改成never 否则已生成的job会被初始化掉
    initialize-schema: never
    properties:
      org:
        quartz:
          scheduler:
            instanceName: MyScheduler
            instanceId: AUTO
          jobStore:
            class: org.quartz.impl.jdbcjobstore.JobStoreTX
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
            tablePrefix: QRTZ_
            isClustered: true
            clusterCheckinInterval: 10000
            useProperties: false
          threadPool:
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 10
            threadPriority: 5
            threadsInheritContextClassLoaderOfInitializingThread: true

 

3、启动执行,数据库默认生成,后续将always改为never,不然插入的任务数据会被清空

 4、业务代码实现定时任务

4.1、实体类

import lombok.Data;

import java.io.Serializable;

@Data
public class QuartzBean implements Serializable {
    /**
     * 任务id
     */
    private String id;
    
    /**
     * 任务名称
     */
    private String jobName;
    
    /**
     * 任务执行类
     */
    private String jobClass;
    
    /**
     * 组名
     */
    private String groupName;
    
    /**
     * 任务 参数信息
     */
    private String jobParam;
    
    /**
     * 任务状态 启动还是暂停
     */
    private Integer status;
    
    /**
     * 任务运行时间表达式
     */
    private String cronExpression;
}

4.2、工具类

import com.alibaba.fastjson.JSON;
import com.nwcs.ioa.xigma.wf.dto.QuartzBean;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.util.ObjectUtils;

import java.util.*;

/**
 * 任务工具类
 *
 * @author yuejianli
 * @date 2023-01-04
 */
public class QuartzUtils {
    /**
     * 获取所有的定时任务
     *
     * @throws Exception
     */
    public static List<QuartzBean> getAllJob(Scheduler scheduler) {
        GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
        List<QuartzBean> jobList = new ArrayList();
        try {
            Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
            for (JobKey jobKey : jobKeys) {
                List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                for (Trigger trigger : triggers) {
                    QuartzBean job = new QuartzBean();
                    job.setJobName(jobKey.getName());
                    job.setGroupName(jobKey.getGroup());
                    Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                    job.setStatus(Trigger.TriggerState.NORMAL.equals(triggerState) ? 1 : 0);
                    if (trigger instanceof CronTrigger) {
                        CronTrigger cronTrigger = (CronTrigger) trigger;
                        String cronExpression = cronTrigger.getCronExpression();
                        job.setCronExpression(cronExpression);
                    }
                    JobDetail jobDetail = scheduler.getJobDetail(jobKey);
                    JobDataMap jobDataMap = jobDetail.getJobDataMap();
                    String[] keys = jobDataMap.getKeys();
                    if (keys != null && keys.length > 0) {
                        Map<String, String> paramMap = new HashMap<>(keys.length, 1.0f);
                        for (String key : keys) {
                            paramMap.put(key, jobDataMap.get(key).toString());
                        }
                        String paramStr = JSON.toJSONString(paramMap);
                        job.setJobParam(paramStr);
                    }
                    Class<? extends Job> jobClass = jobDetail.getJobClass();
                    job.setJobClass(jobClass.getName());
                    jobList.add(job);
                }
            }
            
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return jobList;
    }
    
    /**
     * 创建定时任务 定时任务创建之后默认启动状态
     *
     * @param scheduler  调度器
     * @param quartzBean 定时任务信息类
     * @throws Exception
     */
    public static void createScheduleJob(Scheduler scheduler, QuartzBean quartzBean) {
        try {
            //获取到定时任务的执行类  必须是类的绝对路径名称
            //定时任务类需要是job类的具体实现 QuartzJobBean是job的抽象类。
            Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(quartzBean.getJobClass());
            // 构建定时任务信息
            JobBuilder jobBuilder = JobBuilder.newJob(jobClass).withIdentity(quartzBean.getJobName(), quartzBean.getGroupName());
            
            // 设置参数
            Map<String, String> paramHashMap = JSON.parseObject(quartzBean.getJobParam(), HashMap.class);
            if (!ObjectUtils.isEmpty(paramHashMap)) {
                paramHashMap.forEach(
                        (param, paramValue) -> {
                            jobBuilder.usingJobData(param, paramValue);
                        }
                );
            }
            JobDetail jobDetail = jobBuilder
                    .storeDurably()
                    .build();
            // 设置定时任务执行方式
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzBean.getCronExpression());
            // 构建触发器trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(quartzBean.getJobName()).withSchedule(scheduleBuilder).build();
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (ClassNotFoundException e) {
            System.out.println("定时任务类路径出错:请输入类的绝对路径");
        } catch (SchedulerException e) {
            System.out.println("创建定时任务出错:" + e.getMessage());
        }
    }
    
    /**
     * 根据任务名称暂停定时任务
     *
     * @param scheduler  调度器
     * @param jobKeyName 定时任务名称
     * @throws SchedulerException
     */
    public static void pauseScheduleJob(Scheduler scheduler, String jobKeyName) {
        String[] jobNameGroupArr = jobKeyName.split("\\.");
        JobKey jobKey = JobKey.jobKey(jobNameGroupArr[1], jobNameGroupArr[0]);
        try {
            scheduler.pauseJob(jobKey);
        } catch (SchedulerException e) {
            System.out.println("暂停定时任务出错:" + e.getMessage());
        }
    }
    
    /**
     * 根据任务名称恢复定时任务
     *
     * @param scheduler  调度器
     * @param jobKeyName 定时任务名称
     * @throws SchedulerException
     */
    public static void resumeScheduleJob(Scheduler scheduler, String jobKeyName) {
        String[] jobNameGroupArr = jobKeyName.split("\\.");
        JobKey jobKey = JobKey.jobKey(jobNameGroupArr[1], jobNameGroupArr[0]);
        try {
            scheduler.resumeJob(jobKey);
        } catch (SchedulerException e) {
            System.out.println("启动定时任务出错:" + e.getMessage());
        }
    }
    
    /**
     * 根据任务名称立即运行一次定时任务
     *
     * @param scheduler  调度器
     * @param jobKeyName 定时任务名称
     * @throws SchedulerException
     */
    public static void runOnce(Scheduler scheduler, String jobKeyName) {
        String[] jobNameGroupArr = jobKeyName.split("\\.");
        JobKey jobKey = JobKey.jobKey(jobNameGroupArr[1], jobNameGroupArr[0]);
        try {
            scheduler.triggerJob(jobKey);
        } catch (SchedulerException e) {
            System.out.println("运行定时任务出错:" + e.getMessage());
        }
    }
    
    /**
     * 更新定时任务
     *
     * @param scheduler  调度器
     * @param quartzBean 定时任务信息类
     * @throws SchedulerException
     */
    public static void updateScheduleJob(Scheduler scheduler, QuartzBean quartzBean) {
        deleteScheduleJob(scheduler, quartzBean.getGroupName() + "." + quartzBean.getJobName());
        createScheduleJob(scheduler, quartzBean);
    }
    
    /**
     * 根据定时任务名称从调度器当中删除定时任务
     *
     * @param scheduler  调度器
     * @param jobKeyName 定时任务名称
     * @throws SchedulerException
     */
    public static void deleteScheduleJob(Scheduler scheduler, String jobKeyName) {
        String[] jobNameGroupArr = jobKeyName.split("\\.");
        JobKey jobKey = JobKey.jobKey(jobNameGroupArr[1], jobNameGroupArr[0]);
        try {
            if (ObjectUtils.isEmpty(jobKey)) {
                return;
            }
            scheduler.deleteJob(jobKey);
        } catch (SchedulerException e) {
            System.out.println("删除定时任务出错:" + e.getMessage());
        }
    }
}

 

 

4.3、控制类

import xx.entity.QuartzBean;
import xx.exception.BizException;
import xx.utils.QuartzUtils;
import xx.web.Result;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.quartz.Scheduler;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@Tag(name = "quartz任务", description = "任务相关接口")
@RestController
@RequestMapping("/common/quartz/")
public class ScheduledController {
    
    
    /**
     * 注入任务调度
     */
    @Resource
    private Scheduler scheduler;
    
    @RequestMapping("get-all")
    public Result<?> getAll() {
        try {
            return new Result<>().ok(QuartzUtils.getAllJob(scheduler));
        } catch (Exception e) {
            throw new BizException("quartz-error-10001", new String[]{e.getMessage()});
        }
    }
    
    /**
     * 创建任务
     */
    @RequestMapping("create-job")
    public Result<?> createJob(@RequestBody QuartzBean quartzBean) {
        try {
            QuartzUtils.createScheduleJob(scheduler, quartzBean);
        } catch (Exception e) {
            throw new BizException("quartz-error-10002", new String[]{e.getMessage()});
        }
        return new Result<>().ok("Quartz任务创建成功");
    }
    
    @RequestMapping("pause-job")
    public Result<?> pauseJob(@RequestParam(name = "job-name") String jobName) {
        try {
            QuartzUtils.pauseScheduleJob(scheduler, jobName);
        } catch (Exception e) {
            throw new BizException("quartz-error-10003", new String[]{e.getMessage()});
        }
        return new Result<>().ok("Quartz任务暂停成功");
    }
    
    @RequestMapping("run-once")
    public Result<?> runOnce(@RequestParam(name = "job-name") String jobName) {
        try {
            QuartzUtils.runOnce(scheduler, jobName);
        } catch (Exception e) {
            throw new BizException("quartz-error-10004", new String[]{e.getMessage()});
        }
        return new Result<>().ok("Quartz任务运行一次成功");
    }
    
    /**
     * 重启任务(恢复定时任务)
     */
    @RequestMapping("resume")
    public Result<?> resume(@RequestParam(name = "job-name") String jobName) {
        try {
            QuartzUtils.resumeScheduleJob(scheduler, jobName);
        } catch (Exception e) {
            throw new BizException("quartz-error-10005", new String[]{e.getMessage()});
        }
        return new Result<>().ok("Quartz任务恢复定时任务成功");
    }
    
    /**
     * 删除任务
     */
    @RequestMapping("/delete")
    public Result<?> delete(@RequestParam(name = "job-name") String jobName) {
        try {
            QuartzUtils.deleteScheduleJob(scheduler, jobName);
        } catch (Exception e) {
            throw new BizException("quartz-error-10006", new String[]{e.getMessage()});
        }
        return new Result<>().ok("Quartz任务删除任务成功");
    }
    
    
    /**
     * 更新任务
     */
    @RequestMapping("/update")
    public Result<?> update(@RequestBody QuartzBean quartzBean) {
        try {
            QuartzUtils.updateScheduleJob(scheduler, quartzBean);
        } catch (Exception e) {
            throw new BizException("quartz-error-10007", new String[]{e.getMessage()});
        }
        return new Result<>().ok("Quartz任务更新成功");
    }
}

 

4.4、空参数任务DEMO

import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.springframework.scheduling.quartz.QuartzJobBean;

@Slf4j
public class MyTask extends QuartzJobBean {
    
    
    @Override
    protected void executeInternal(JobExecutionContext context) {
        log.info("空参数任务 {}", context.getJobDetail().getKey());
    }
}

 

4.5、有参数任务DEMO

import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.springframework.scheduling.quartz.QuartzJobBean;

@Slf4j
public class MyTask extends QuartzJobBean {
    
    
    @Override
    protected void executeInternal(JobExecutionContext context) {
        log.info("InterfaceLogAlertTask {}", context.getJobDetail().getKey());
        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
        log.info("InterfaceLogAlertTask jobDataMap {}", JSON.toJSONString(jobDataMap));
        String start_date = jobDataMap.get("start_date").toString();
        String end_date = jobDataMap.get("end_date").toString();
        if ((jobDataMap.containsKey("start_date") && !StringUtils.isNullOrEmpty(start_date)) && (jobDataMap.containsKey("end_date") && !StringUtils.isNullOrEmpty(end_date))) {
            interfaceLogService.syncAlert(start_date, end_date);
            return;
        }
        interfaceLogService.syncAlert(null, null);
    }
}

 

 

 

测试结果:

 

 

 

 

 

 

 

 

 

 

标签:Quartz,SpringBoot,任务,quartz,scheduler,new,import,定时,String
From: https://www.cnblogs.com/todarcy/p/18025409

相关文章

  • 在阿里云部署javaspringboot项目
    记住自己服务器的账号密码配置安全组  用xshell连接服务器(xftp同理) 到官网去下载jdk的Linux版本,官网地址:https://www.oracle.com/technetwork/java/javase/downloads 安装JDK我自己用的是jdk21,下载完毕后用xftp传到服务器上(解压一下)#tar-zxvf压缩包.tar.......
  • SpringBoot+MybatisPlus+Mysql实现批量插入万级数据多种方式与耗时对比
    场景若依前后端分离版本地搭建开发环境并运行项目的教程:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108465662若依前后端分离版如何集成的mybatis以及修改集成mybatisplus实现Mybatis增强:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1362030......
  • SpringBoot使用git-commit-id-maven-plugin打包
    简介git-commit-id-maven-plugin是一个maven插件,用来在打包的时候将git-commit信息打进jar中。这样做的好处是可以将发布的某版本和对应的代码关联起来,方便查阅和线上项目的维护。至于它的作用,用官方说法,这个功能对于大型分布式项目来说是无价的。功能你是否经常遇到这样的......
  • 华为二面:SpringBoot如何自定义Starter?
    SpringBoot的自动配置机制为开发人员提供了一种轻松集成和配置各种功能的便捷方式。然而,随着项目的复杂性增加,更好地组织和分享通用功能变得至关重要。自定义Starter成为了理想的解决方案,旨在简化项目的依赖管理和自动配置,使开发者能够迅速而灵活地集成特定的功能模块。本文将深......
  • SpringBoot应用“No primary or single unique constructor found for interface java
    Bug复现今天在写SpringBoot应用时,写一个后端生成图形验证码的业务时,需要用到session保存后端生成的图形验证码的Base64编码,然后前端通过session来显示图形验证码。代码里用到了servlet里的HttpSession类,于是idea自动导入了javax.servlet包里的HttpSession。业务代码如下:packag......
  • Windows高精度定时器
     自从上次封装微秒延时函数后,利用空闲时间试着封装一个微秒定时器(类似MFC定时器形式)使用起来效果还不错。 关于定时器的几点介绍:  1.设计采用了自动释放定时器节点方式(增加虚析构函数在内部做相关释放判断,即使用完不释放节点也没关系);  2.设计采用了双向链表方......
  • 【转载】linux利用crontab添加定时任务详解
    crontab作用:添加,查询,删除系统计划任务的指令。[root@localhost~]#crontab[选项]选项:   -e:   编辑crontab定时任务   -l:   查询crontab任务   -r:   删除当前用户所有的crontab任务1234512345[root@localhost~]#crontab-e......
  • SpringBoot中使用PageHelper插件实现Mybatis分页
    场景SpringBoot中整合Mybatis时一般添加的依赖为       <dependency>           <groupId>org.mybatis.spring.boot</groupId>           <artifactId>mybatis-spring-boot-starter</artifactId>           <version>2.2.1</vers......
  • 编程开发 --- springboot参考文档之概述
    该文档来自于官方,本人只是翻译通顺、忽略废话、术语通俗解释、代码注释等优化工作,目的只是让我们更快的理解它。https://github.com/spring-projects/spring-boot/wiki   第一章法律版权声明  spring.io ©2012-2024您可以复制本文件供自己使用或分发给他人,但不得......
  • 基于Java+SpringBoot+vue的采购管理系统(源码及功能分析)
    前言:随着全球化和信息化的发展,企业采购管理面临越来越多的挑战。传统的采购方式往往涉及到多个繁琐的步骤,包括供应商筛选、询价、招投标等,这些过程不仅耗时,而且容易出错。为了解决这些问题,供应商、询价、招投标一体化系统应运而生。该系统通过集成供应商管理、询价管理、招投标......