zoukankan      html  css  js  c++  java
  • 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();
                }
            });
        }
    }
    
    
  • 相关阅读:
    使用CustomValidate自定义验证控件
    C#中金额的大小写转换
    Andriod出错之Unable to build: the file dx.jar was not loaded from the SDK folder!
    VC 编写的打字练习
    机房工作笔记Ping只有单向通
    web服务协同学习笔记(1)
    Dll 学习3 将MDI子窗口封装在DLL中
    机房工作学习文件共享
    Andriod出错之Failed to find an AVD compatible with target 'Android 2.2'
    Andriod出错之wrapper was not properly loaded first
  • 原文地址:https://www.cnblogs.com/JaxYoun/p/13467151.html
Copyright © 2011-2022 走看看