关于springboot:SpringBoot实现quartz定时任务可视化管理

3次阅读

共计 7337 个字符,预计需要花费 19 分钟才能阅读完成。

前言

在理论框架或产品开发过程中,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);
        }
    }

}

界面展现

正文完
 0