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 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 jobClass = (Class) 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 jobClass = (Class) 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 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 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);
        }
    }

}

界面展示

SpringBoot实现quartz定时任务可视化管理功能_第1张图片

SpringBoot实现quartz定时任务可视化管理功能_第2张图片

到此这篇关于SpringBoot实现quartz定时任务可视化管理的文章就介绍到这了,更多相关SpringBoot 定时任务可视化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

你可能感兴趣的:(SpringBoot实现quartz定时任务可视化管理功能)