• SpringBoot整合持久化功能的Quartz


    单体应用,任务持久化到数据库,省略了数据库交互的代码

    package com.yang.springbootquartz.rest;
    
    import lombok.Data;
    import lombok.extern.slf4j.Slf4j;
    import org.quartz.*;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.annotation.Resource;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author: Yang
     * @date: 2018/8/9 22:54
     * @description: 前台的调度任务持久化到数据库
     * 每个任务需要有唯一key,避免重复任务
     */
    @Slf4j
    @RestController
    @RequestMapping("/my")
    public class MyQuartzController {
    
        @Resource
        private Scheduler scheduler;
    
        /**
         * 添加调度任务
         */
        @PostMapping("/add")
        private void add(@RequestBody Task task) throws Exception {
            //1.查询数据库,避免重复复
            //2.任务入库
            //3.删除任务,防止重复
            this.deleteFromQuartz(task.getJobClassName());
            //4.将任务托管给quartz
            this.addToQuartz(task.getJobClassName(), task.getCronExpression(), task.getParam());
            //5.将数据库中对应记录的状态修改为已托管
        }
    
        /**
         * 将任务托管到Quartz框架
         *
         * @param className
         * @param cronExpression
         * @param param
         */
        void addToQuartz(String className, String cronExpression, String param) throws Exception {
            //0.利用Quartz内置方法,校验cron表达式的合法性,前端可用此正则【/^[a-zA-Z]+(.([a-zA-Z])+)+$/】进行校验
            if (!CronExpression.isValidExpression(cronExpression)) {
                log.error("cron表达式不合法");
                return;
            }
    
            // 1.构建job信息
            JobDetail jobDetail = JobBuilder
                    .newJob(getClass(className).getClass())
                    .withIdentity(className)
                    .usingJobData("param", param)
                    .build();
    
            // 2.表达式调度构建器(即任务执行的时间)
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
    
            // 3.按新的cronExpression表达式构建一个新的trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(className).withSchedule(scheduleBuilder).build();
    
            // 4.装载job和trigger
            this.scheduler.scheduleJob(jobDetail, trigger);
    
            // 5.启动调度器
            this.scheduler.start();
        }
    
        /**
         * 删除调度任务
         *
         * @param task
         * @throws SchedulerException
         */
        @PostMapping("/delete")
        public void delete(@RequestBody Task task) throws SchedulerException {
            //1.删除已托管到quartz中的任务
            this.deleteFromQuartz(task.getJobClassName());
            //2.删除数据库记录
        }
    
        /**
         * @param className
         */
        void deleteFromQuartz(String className) throws SchedulerException {
            //1.暂停任务的trigger
            this.scheduler.pauseTrigger(TriggerKey.triggerKey(className));
    
            //2.取消任务的调度
            this.scheduler.unscheduleJob(TriggerKey.triggerKey(className));
    
            //3.删除任务
            this.scheduler.deleteJob(JobKey.jobKey(className));
        }
    
        private static Job getClass(String className) throws Exception {
            Class<?> class1 = Class.forName(className);
            return (Job) class1.newInstance();
        }
    
    }
    
    @Data
    class Task {
    
        //任务唯一标识,可以根据业务,考虑替换目前以className为标记的实现
        private String taskKey;
    
        //任务类名,类名应该以下拉的方式呈现,供前端选择
        private String jobClassName;
    
        //cron表达式,需要校验
        private String cronExpression;
    
        //任务参数
        private String param;
    }
    
    /**
     * 项目重启时,需要将已经持久化的任务全部重新托管给Quartz,所以需要在项目启动后,对Quartz进行初始化
     */
    @Order(100)
    @Component
    class QuartzTaskInitializer implements CommandLineRunner {
    
        @Resource
        private MyQuartzController myQuartzController;
    
        @Override
        public void run(String... args) throws Exception {
            //1.从数据库查询出所有未删除,且状态为已托管的任务记录列表
            List<Task> taskList = new ArrayList<>();
            //2.便利重新托管
            taskList.forEach(it -> {
                try {
                    this.myQuartzController.deleteFromQuartz(it.getJobClassName());
                    this.myQuartzController.addToQuartz(it.getJobClassName(), it.getCronExpression(), it.getParam());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
    }
    
    
  • 相关阅读:
    聊天ListView
    Android笔试题三
    java内存分配与垃圾回收
    Activity切换的时候生命周期的变化
    二分查找
    如何用报表工具实现树状层级结构的填报表
    报表数据填报中的自动计算
    报表数据填报中的合法性校验
    tab 页形式展现多张报表
    报表工具之数据校验竟可以如此简单
  • 原文地址:https://www.cnblogs.com/JaxYoun/p/13467151.html
Copyright © 2020-2023  润新知