zoukankan      html  css  js  c++  java
  • SpringBoot实现quartz定时任务可视化管理

    前言

    在实际框架或产品开发过程中,springboot中集成quarzt方式基本是以job和trigger的bean对象方式直接硬编码完成的,例如以下代码示例。对于系统内定义的所有定时任务类型,具体执行类,执行策略,运行状态都没有一个动态全局的管理,所有决定将quartz做成可视化配置管理,便于统一管理,也降低了使用门槛,只需要关心job类的实现即可

        @Bean
        public JobDetail SMSJobDetail() {
            return JobBuilder.newJob(SMSJob.class).withIdentity("SMSJob").storeDurably().build();
        }
    
        // 把jobDetail注册到trigger上去
        @Bean
        public Trigger myJobTrigger() {
            SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                    .withIntervalInSeconds(1).repeatForever();
    
            return TriggerBuilder.newTrigger()
                    .forJob(SMSJobDetail())
                    .withIdentity("myJobTrigger")
                    .withSchedule(scheduleBuilder)
                    .build();
        }
    

    表结构

    用于存储quartz配置

    DROP TABLE IF EXISTS `f_quartztask`;
    CREATE TABLE `f_quartztask` (
      `TaskID` varchar(50) NOT NULL,
      `TaskName` varchar(200) DEFAULT NULL,
      `TaskType` int(11) DEFAULT NULL,
      `TaskTag` varchar(100) DEFAULT NULL,
      `JobClassPath` varchar(200) DEFAULT NULL,
      `ExecutePeroid` int(11) DEFAULT NULL,
      `ExecuteUnit` int(11) DEFAULT NULL,
      `CornExpress` varchar(200) DEFAULT NULL,
      `Enviroment` varchar(50) DEFAULT NULL,
      `TaskStatus` int(11) DEFAULT NULL,
      `SortNum` int(11) DEFAULT NULL,
      `Remark` varchar(500) DEFAULT NULL,
      PRIMARY KEY (`TaskID`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    

    枚举类

    public class QuartzEnum {
        public enum TaskType implements IConvertEnumToCodeItem {
            Cycle(10, "循环任务"), Corn(20, "Corn表达式任务");
            private int _value;
            private String _name;
    
            private TaskType(int value, String name) {
                set_value(value);
                set_name((name));
            }
    
            public int get_value() {
                return _value;
            }
    
            public void set_value(int _value) {
                this._value = _value;
            }
    
            public String get_name() {
                return _name;
            }
    
            public void set_name(String _name) {
                this._name = _name;
            }
    
            @Override
            public String toString() {
                return _name;
            }
    
            @Override
            public String getCodeName() {
                return "Quartz任务类别";
            }
        }
    
        public enum ExecuteUnit implements IConvertEnumToCodeItem {
            Second(10, "秒"), Minute(20, "分"), Hour(30, "时");
            private int _value;
            private String _name;
    
            private ExecuteUnit(int value, String name) {
                set_value(value);
                set_name((name));
            }
    
            public int get_value() {
                return _value;
            }
    
            public void set_value(int _value) {
                this._value = _value;
            }
    
            public String get_name() {
                return _name;
            }
    
            public void set_name(String _name) {
                this._name = _name;
            }
    
            @Override
            public String toString() {
                return _name;
            }
    
            @Override
            public String getCodeName() {
                return "Quartz间隔单位";
            }
        }
    
    
        public enum TaskStatus implements IConvertEnumToCodeItem {
            Open(10, "开启"), Close(20, "关闭");
            private int _value;
            private String _name;
    
            private TaskStatus(int value, String name) {
                set_value(value);
                set_name((name));
            }
    
            public int get_value() {
                return _value;
            }
    
            public void set_value(int _value) {
                this._value = _value;
            }
    
            public String get_name() {
                return _name;
            }
    
            public void set_name(String _name) {
                this._name = _name;
            }
    
            @Override
            public String toString() {
                return _name;
            }
    
            @Override
            public String getCodeName() {
                return "Quartz任务状态";
            }
        }
    
        public enum TaskEnviroment implements IConvertEnumToCodeItem {
            All("全部", "全部"), Dev("dev", "开发环境"), Pro("pro", "正式环境");
            private String _value;
            private String _name;
    
            private TaskEnviroment(String value, String name) {
                set_value(value);
                set_name((name));
            }
    
            public String get_value() {
                return _value;
            }
    
            public void set_value(String _value) {
                this._value = _value;
            }
    
            public String get_name() {
                return _name;
            }
    
            public void set_name(String _name) {
                this._name = _name;
            }
    
            @Override
            public String toString() {
                return _name;
            }
    
            @Override
            public String getCodeName() {
                return "Quartz任务执行环境";
            }
        }
    }
    

    QuartzFactory

    支持Job类注bean入对象

    @Component
    public class QuartzFactory extends AdaptableJobFactory {
        @Autowired
        private AutowireCapableBeanFactory capableBeanFactory;
    
        @Override
        protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
            // 调用父类的方法
            Object jobInstance = super.createJobInstance(bundle);
            // 进行注入
            capableBeanFactory.autowireBean(jobInstance);
            return jobInstance;
    
        }
    }
    

    QuartzConfig

    注入QuartzFactory对象

    @Configuration
    public class QuartzConfig {
        @Autowired
        private QuartzFactory quartzFactory;
    
        @Bean
        public SchedulerFactoryBean schedulerFactoryBean(){
            SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
            schedulerFactoryBean.setJobFactory(quartzFactory);
            //将job实例化,能够操作进行Spring 注入
            return schedulerFactoryBean;
        }
    }
    

    QuartzUtil

    定时任务动态添加/删除操作类,initQuartzTask方法在系统启动时执行,根据配置自动开启相关符合条件的任务

    @Component
    public class QuartzUtil {
        @Autowired
        private SchedulerFactoryBean schedulerFactoryBean;
        @Autowired
        private F_QuartzTaskService quartzTaskService;
        @Value("${spring.profiles.active}")
        private String active;
        private static String JOB_GROUP_NAME = "DEFAULT_JOB_GROUP_NAME";
        private static String TRIGGER_GROUP_NAME = "DEFAULT_TRIGGER_GROUP_NAME";
    
    
        public void initQuartzTask() {
            List<F_QuartzTaskDO> openTaskList = quartzTaskService.selectAllList();
            if(openTaskList.size()>0){
                openTaskList = openTaskList.stream().filter(a -> a.getTaskStatus() == QuartzEnum.TaskStatus.Open.get_value() &&
                        (a.getEnviroment().equals(QuartzEnum.TaskEnviroment.All.get_name()) || a.getEnviroment().equals(active))).collect(Collectors.toList());
            }
            for (F_QuartzTaskDO taskDO : openTaskList) {
                try {
                    Class<Job> jobClass = (Class<Job>) Class.forName(taskDO.getJobClassPath());
                    if (taskDO.getTaskType() == QuartzEnum.TaskType.Cycle.get_value()) {
                        addIntervalJob(taskDO.getTaskTag(), jobClass, taskDO.getExecutePeroid(), taskDO.getExecuteUnit());
                    } else {
                        addCornJob(taskDO.getTaskTag(), jobClass, taskDO.getCornExpress());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (openTaskList.size() > 0) {
                System.out.println("扫描并初始化开启quartz定时任务成功,任务数量:" + openTaskList.size() + "个");
            }
        }
    
        public void startTask( F_QuartzTaskDO taskDO){
            try {
                Class<Job> jobClass = (Class<Job>) Class.forName(taskDO.getJobClassPath());
                if (taskDO.getTaskType() == QuartzEnum.TaskType.Cycle.get_value()) {
                    addIntervalJob(taskDO.getTaskTag(), jobClass, taskDO.getExecutePeroid(), taskDO.getExecuteUnit());
                } else {
                    addCornJob(taskDO.getTaskTag(), jobClass, taskDO.getCornExpress());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        //增加定时任务任务
        public void addIntervalJob(String jobName, Class<? extends Job> cls, int peroid, int timeUnit) {
            try {
                SimpleScheduleBuilder scheduleBuilder = null;
                if (timeUnit == QuartzEnum.ExecuteUnit.Second.get_value()) {
                    scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(peroid).repeatForever();
                } else if (timeUnit == QuartzEnum.ExecuteUnit.Minute.get_value()) {
                    scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInMinutes(peroid).repeatForever();
                } else if (timeUnit == QuartzEnum.ExecuteUnit.Hour.get_value()) {
                    scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInHours(peroid).repeatForever();
                }
                Scheduler sched = schedulerFactoryBean.getScheduler();
                JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).storeDurably().build();
                Trigger trigger = TriggerBuilder.newTrigger().forJob(jobDetail).withIdentity(jobName, TRIGGER_GROUP_NAME).withSchedule(scheduleBuilder).build();
    
                sched.scheduleJob(jobDetail, trigger);
                if (!sched.isShutdown()) {
                    sched.start();        // 启动
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        //增加corn表达式任务
        public void addCornJob(String jobName, Class<? extends Job> cls, String cornExpress) {
            try {
                Scheduler sched = schedulerFactoryBean.getScheduler();
                JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).build();
                CronTrigger trigger = (CronTrigger) TriggerBuilder
                        .newTrigger()
                        .withIdentity(jobName, TRIGGER_GROUP_NAME)
                        .withSchedule(CronScheduleBuilder.cronSchedule(cornExpress))
                        .build();
                sched.scheduleJob(jobDetail, trigger);
                if (!sched.isShutdown()) {
                    sched.start();        // 启动
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        //停止任务
        public void deleteJob(String jobName) {
            try {
                Scheduler sched = schedulerFactoryBean.getScheduler();
                TriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME);
                JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);
                sched.pauseTrigger(triggerKey); // 停止触发器
                sched.unscheduleJob(triggerKey);// 移除触发器
                sched.deleteJob(jobKey);        // 删除任务
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
    }
    

    界面展示

  • 相关阅读:
    Python第一周作业
    turtle库的学习笔记
    绘制五角星
    绘制六角形
    绘制同心圆
    绘制叠加三角形
    Slash And Black Slash/正斜杠和反斜杠
    OpenCv中avi视频的读取问题,以及内部格式要求
    OpenCv和matlab对图像的读取
    个人项目进度
  • 原文地址:https://www.cnblogs.com/yanpeng19940119/p/15202177.html
Copyright © 2011-2022 走看看