Springboot 通過Schedule實現定時任務動態增、刪、改、啟動、暫停
缺點:1、不支持分布式 (關於分布式任務調度會選擇xxl-job或elasticjob, xxl-job:https://www.xuxueli.com/xxl-job)
2、本人未做界面開發,但是Controller層全部都已經定義好。
由於代碼太多,值粘出部分代碼,大家可以下載項目源碼看看
數據庫
CREATE TABLE `schedule_setting` ( `id` int(11) NOT NULL AUTO_INCREMENT, `job_name` varchar(255) DEFAULT NULL, `class_name` varchar(255) DEFAULT NULL, `method` varchar(255) DEFAULT NULL, `cron` varchar(255) DEFAULT NULL, `status` int(2) DEFAULT NULL COMMENT '0 代表開啟,1代表關閉', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
Controller層
@RestController @RequestMapping("/timmer") public class TimmerController { @Autowired private TimmerServiceImpl timmerServiceImpl; /** * 添加任務 * @return */ @GetMapping("/add") public ReponseData addTask(){ ReponseData res = new ReponseData(); try { timmerServiceImpl.addTask(); res.setCode(0); res.setMsg("添加成功"); } catch (Exception e){ res.setCode(1); res.setMsg("添加失敗"); } return res; } /** * 修改任務 * @return */ @GetMapping("/update") public ReponseData updateTask(){ ReponseData res = new ReponseData(); try { timmerServiceImpl.updateTask(); res.setCode(0); res.setMsg("修改成功"); } catch (Exception e){ System.out.println(e.toString()); res.setCode(1); res.setMsg("修改失敗"); } return res; } /** * 暫停任務 */ @GetMapping("/pause") public ReponseData pauseTask(){ ReponseData res = new ReponseData(); try { timmerServiceImpl.pauseTask(); res.setCode(0); res.setMsg("暫停成功"); } catch (Exception e){ res.setCode(1); res.setMsg("暫停失敗"); } return res; } /** * 開啟任務 */ @GetMapping("/start") public ReponseData startTask(){ ReponseData res = new ReponseData(); try { timmerServiceImpl.startTask(); res.setCode(0); res.setMsg("開啟成功"); } catch (Exception e){ res.setCode(1); res.setMsg("開啟失敗"); } return res; } /** * 刪除任務 */ @GetMapping("/del") public ReponseData delTask(){ ReponseData res = new ReponseData(); try { timmerServiceImpl.deleteTask(); res.setCode(0); res.setMsg("刪除成功"); } catch (Exception e){ res.setCode(1); res.setMsg("刪除失敗"); } return res; } }
定時任務核心
@Component public class TimmerComponent { // 保存任務 private Map<String, ScheduledFuture<?>> futuresMap = new ConcurrentHashMap<String, ScheduledFuture<?>>(); @Autowired private TimmerDao timmerDao; // 創建ThreadPoolTaskScheduler線程池 @Autowired private ThreadPoolTaskScheduler threadPoolTaskScheduler; @Bean public ThreadPoolTaskScheduler threadPoolTaskScheduler() { ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); threadPoolTaskScheduler.setPoolSize(10); return threadPoolTaskScheduler; } // 初始化任務 @Bean public void initTimmer(){ List<ScheduleConfig> list = timmerDao.getScheduleList(); for (ScheduleConfig s : list){ ScheduledFuture<?> future = threadPoolTaskScheduler.schedule(getRunnable(s), getTrigger(s)); futuresMap.put(s.getJobName(), future); } } /** * 添加任務 * @param s */ public void addTask(ScheduleConfig s){ ScheduledFuture<?> future = threadPoolTaskScheduler.schedule(getRunnable(s), getTrigger(s)); futuresMap.put(s.getJobName(), future); } /** * 暫停任務 * @param key * @return */ public boolean pauseeTask(String key) { ScheduledFuture toBeRemovedFuture = futuresMap.remove(key); if (toBeRemovedFuture != null) { toBeRemovedFuture.cancel(true); return true; } else { return false; } } /** * 更新任務 * @param s */ public void updateTask(ScheduleConfig s) { ScheduledFuture toBeRemovedFuture = futuresMap.remove(s.getJobName()); if (toBeRemovedFuture != null) { toBeRemovedFuture.cancel(true); } addTask(s); } /** * 轉換首字母小寫 * * @param str * @return */ public static String lowerFirstCapse(String str) { char[] chars = str.toCharArray(); chars[0] += 32; return String.valueOf(chars); } /** * runnable * @param scheduleConfig * @return */ private Runnable getRunnable(ScheduleConfig scheduleConfig){ return new Runnable() { @Override public void run() { Class<?> clazz; try { clazz = Class.forName(scheduleConfig.getClassName()); String className = lowerFirstCapse(clazz.getSimpleName()); Object bean = (Object) ApplicationContextHelper.getBean(className); Method method = ReflectionUtils.findMethod(bean.getClass(), scheduleConfig.getMethod()); ReflectionUtils.invokeMethod(method, bean); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }; } /** * Trigger * @param scheduleConfig * @return */ private Trigger getTrigger(ScheduleConfig scheduleConfig){ return new Trigger() { @Override public Date nextExecutionTime(TriggerContext triggerContext) { CronTrigger trigger = new CronTrigger(scheduleConfig.getCron()); Date nextExec = trigger.nextExecutionTime(triggerContext); return nextExec; } }; } }
————————————————
原文鏈接:https://blog.csdn.net/xcc_2269861428/article/details/100023788