springboot 框架 +quartz 动态定时器 单表

前言

项目中 需要集合 quartz 定时器,本篇文章 底层框架为springboot +quartz,任务会写入到数据库

提示:以下是本篇文章正文内容,下面案例可供参考

一、建立定时任务表 和导入依赖

示例:

CREATE TABLE `sys_quartz_task` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `class_name` varchar(255) NOT NULL COMMENT '全类名,反射用',
  `cron` varchar(255) NOT NULL COMMENT '表达式',
  `job_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '任务名称',
  `job_group_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务组名,相同任务分组一般不同',
  `trigger_name` varchar(255) NOT NULL COMMENT '调度名',
  `trigger_group_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '调度分组',
  `status` int NOT NULL DEFAULT '1' COMMENT '状态  0  取消执行   1  执行',
  `described` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '描述',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb3;

cf7b3d64eebf4a7e9020270fe43fbc99.png

导入依赖

<!--定时任务 -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-jobs</artifactId>
            <version>2.2.1</version>
        </dependency>

二、代码

quartz 配置

代码如下(示例):可建可不建这个类,有默认实现

@Configuration
public class QuartzFactoryBean implements SchedulerFactoryBeanCustomizer {
    @Override
    public void customize(SchedulerFactoryBean schedulerFactoryBean) {
        schedulerFactoryBean.setStartupDelay(10);
        schedulerFactoryBean.setOverwriteExistingJobs(true);
    }
}

ApplicationRunnerImpl 启动容器执行的类

代码如下:这个是应用启动时,会执行该方法,从而启动所有的定时任务

@Component
public class ApplicationRunnerImpl implements ApplicationRunner {
    @Autowired
    private SysQuartzTaskDao sysQuartzTaskDao;
    @Override
    public void run(ApplicationArguments args){

         SysQuartzTask tasks = new SysQuartzTask();
        List<SysQuartzTask> tasksList = sysQuartzTaskDao.selectList(
                new QueryWrapper<SysQuartzTask>().eq("status",1));

            tasksList.forEach(item->{

                try {
                    QuartzManager.addJob(item.getJobName(),item.getJobGroupName(),item.getTriggerName(),
                            item.getTriggerGroupName(),Class.forName(item.getClassName()),item.getCron());
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }

            });



    }

}

任务类

代码如下:任务类,将这个类的全类名写入到数据库

/*
@Author 
 *@Description DisallowConcurrentExecution不允许并发执行
 **/
@DisallowConcurrentExecution
public class TestJob  extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("test quartz");
    }
}

定时任务工具类

代码如下: 定时任务调用的工具类

public class QuartzManager {
    //应用启动后,Scheduler已经装配到ioc容器中了,无需重新new一个
    private static Scheduler scheduler = SpringContextUtils.getBean(Scheduler.class);

    public static void addJob(String jobName, String jobGroupName,
                              String triggerName, String triggerGroupName, Class jobClass, String cron) {
        try {
            // 任务名,任务组,任务执行类
            JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();

            // 触发器
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
            // 触发器名,触发器组
            triggerBuilder.withIdentity(triggerName, triggerGroupName);
            triggerBuilder.startNow();
            // 触发器时间设定
            triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
            // 创建Trigger对象
            CronTrigger trigger = (CronTrigger) triggerBuilder.build();

            // 调度容器设置JobDetail和Trigger
            scheduler.scheduleJob(jobDetail, trigger);

            // 启动   shutdown  停止的意思
            if (!scheduler.isShutdown()) {
                scheduler.start();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 新增  定时任务
     */
    public static void addJob(String jName, String jGroup, String tName, String tGroup, String cron ,String className) {
        try {
            JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(className))
                    .withIdentity(jName, jGroup)
                    .build();
            CronTrigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity(tName, tGroup)
                    .startNow()
                    .withSchedule(CronScheduleBuilder.cronSchedule(cron))
                    .build();
            scheduler.start();
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

        /**
         * 暂停定时任务
         */
        public static void pauseJob (String jName, String jGroup ) {
            try {
                scheduler.pauseJob(JobKey.jobKey(jName, jGroup));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    /**
     * 继续定时任务
     * @param jName
     * @param jGroup
     */
    public static void resumeJob(String jName, String jGroup) {
        try {
            scheduler.resumeJob(JobKey.jobKey(jName, jGroup));
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除定时任务
     * @param jName
     * @param jGroup
     */
    public static void deleteJob(String jName, String jGroup) {
        try {
            JobKey jobKey = new JobKey(jName, jGroup);
            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
            if (jobDetail == null) {
                return;
            }
            scheduler.deleteJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**
     * 恢复所有任务
     *
     * @throws SchedulerException
     */
    public static void resumeAllJob() throws SchedulerException {
        scheduler.resumeAll();
    }

    /**
     * 暂停所有任务
     *
     * @throws SchedulerException
     */
    public static void pauseAllJob() throws SchedulerException {
        scheduler.pauseAll();
    }


    /**
     * 修改某个任务的执行时间
     *
     * @param name 任务名称
     * @param group 任务分组
     * @param time 时间表达式
     * @return
     * @throws SchedulerException
     */
    public static boolean modifyJob(String name, String group, String time) throws SchedulerException {
        Date date = null;
        TriggerKey triggerKey = new TriggerKey(name, group);
        CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        String oldTime = cronTrigger.getCronExpression();
        if (!oldTime.equalsIgnoreCase(time)) {
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(time);
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(name, group)
                    .withSchedule(cronScheduleBuilder).build();
            date = scheduler.rescheduleJob(triggerKey, trigger);
        }
        return date != null;
    }

    /**
     * 获取Job信息
     *
     * @param name 任务名称
     * @param group 任务分组
     * @return
     * @throws SchedulerException
     */
    public static String getJobInfo(String name, String group) throws SchedulerException {
        TriggerKey triggerKey = new TriggerKey(name, group);
        CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        return String.format("time:%s,state:%s", cronTrigger.getCronExpression(),
                scheduler.getTriggerState(triggerKey).name());
    }


}


通过name获取bean 的工具类

代码如下(示例):工具类,通过name获取bean

@Component
public class SpringContextUtils implements ApplicationContextAware {
    /**
     * 上下文对象实例
     */
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    /**
     * 获取applicationContext
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
    /**
     * 通过name获取 Bean.
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }
    /**
     * 通过class获取Bean.
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }
    /**
     * 通过name,以及Clazz返回指定的Bean
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

}

controller 测试使用

controller 接口,测试用

@Api(tags = "定时器")
@RestController
@RequestMapping("quartz")
public class QuartzController {


    @PostMapping("create")
    @Operation(summary = "定时任务-新增")
    public ResponseData<?> create() throws IOException {


        return ResponseData.buildSuccess();
    }

    @RequestMapping("/start")
    @ResponseBody
    public String startQuartzJob() {
        try {
//            QuartzManager.startJob();
        } catch (Exception e) {
            e.printStackTrace();
            return "false";
        }
        return "success";
    }

    @RequestMapping("/info")
    @ResponseBody
    public String getQuartzJob(@RequestParam String name, @RequestParam String group) {
        String info = null;
        try {
            info = QuartzManager.getJobInfo(name, group);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return info;
    }

    @RequestMapping("/modify")
    @ResponseBody
    public boolean modifyQuartzJob(@RequestParam String name,@RequestParam  String group,@RequestParam  String time) {
        boolean flag = true;
        try {
            flag = QuartzManager.modifyJob(name, group, time);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return flag;
    }

    @RequestMapping(value = "/pause")
    @ResponseBody
    public String pauseQuartzJob(@RequestParam String name,@RequestParam  String group) {
        try {
            QuartzManager.pauseJob(name, group);
        } catch (Exception e) {
            e.printStackTrace();
            return "false";
        }
        return "success";
    }

    @RequestMapping(value = "/pauseAll")
    @ResponseBody
    public String pauseAllQuartzJob() {
        try {
            QuartzManager.pauseAllJob();
        } catch (SchedulerException e) {
            e.printStackTrace();
            return "false";
        }
        return "success";
    }

    @RequestMapping(value = "/delete")
    @ResponseBody
    public String deleteJob(@RequestParam String name,@RequestParam  String group) {
        try {
            QuartzManager.deleteJob(name, group);
        } catch (Exception e) {
            e.printStackTrace();
            return "false";
        }
        return "success";
    }


}

如果是多实例部署,一定记得加分布式锁