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"; } }

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