本篇內(nèi)容介紹了“如何實(shí)現(xiàn)集成定時(shí)任務(wù)SchedulingConfigurer”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
成都創(chuàng)新互聯(lián)公司自2013年起,先為桓仁等服務(wù)建站,桓仁等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為桓仁企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。
背景:
項(xiàng)目需要啟動一個(gè)定時(shí)執(zhí)行的任務(wù),該任務(wù)的執(zhí)行可以隨時(shí)停止執(zhí)行,要求在數(shù)據(jù)庫配置執(zhí)行規(guī)律。
調(diào)研:使用scheduling定時(shí)任務(wù)與springboot集成;
實(shí)例:
第一步:創(chuàng)建一個(gè)數(shù)據(jù)表,保存執(zhí)行的任務(wù)
/*DDL 信息*/------------ CREATE TABLE `hk_sys_task` ( `id` bigint(21) NOT NULL AUTO_INCREMENT COMMENT '主鍵', `task_uuid` varchar(50) DEFAULT NULL COMMENT '任務(wù)UUID', `task_name` varchar(50) DEFAULT NULL COMMENT '任務(wù)名稱', `task_cron` varchar(50) DEFAULT NULL COMMENT '任務(wù)定時(shí)表達(dá)式', `class_name` varchar(100) DEFAULT NULL COMMENT '任務(wù)類', `method_name` varchar(100) DEFAULT NULL COMMENT '任務(wù)方法', `task_type` int(1) DEFAULT NULL COMMENT '任務(wù)類型', `remark` varchar(250) DEFAULT NULL, `del_mark` int(1) DEFAULT '1', `flag` int(1) DEFAULT '1', `create_user` varchar(50) DEFAULT NULL, `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `modify_user` varchar(50) DEFAULT NULL, `modify_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
2、創(chuàng)建springboot的SpringUtil用戶獲取bean
/** * @Author: Liu Yue * @Descripition: * @Date; Create in 2021/5/14 11:19 **/ @Component @Slf4j public class SpringUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if(SpringUtil.applicationContext == null) { SpringUtil.applicationContext = applicationContext; } log.info("========ApplicationContext配置成功,在普通類可以通過調(diào)用SpringUtils.getAppContext()獲取applicationContext對象,applicationContext={},",SpringUtil.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); } }
3、配置執(zhí)行任務(wù)的類SysTaskConfig
/** * @Author: Liu Yue * @Descripition: * @Date; Create in 2021/5/14 9:34 **/ @Lazy(value = false) @Component @Slf4j public class SysTaskConfig implements SchedulingConfigurer { @Resource private HkSysTaskMapper hkSysTaskMapper; private static ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); private static Map<String,ScheduledFuture<?>> scheduledFutureMap = new HashMap<>(); //從數(shù)據(jù)庫里取得所有要執(zhí)行的定時(shí)任務(wù) private List<HkSysTask> getAllTasks() { LambdaQueryWrapper<HkSysTask> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(HkSysTask::getDelMark,1) .eq(HkSysTask::getFlag,1); return hkSysTaskMapper.selectList(wrapper); } static { threadPoolTaskScheduler.initialize(); } @Override public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { List<HkSysTask> allTasks = getAllTasks(); log.info("定時(shí)任務(wù)啟動,預(yù)計(jì)啟動任務(wù)數(shù)量={},; time={}",allTasks.size(),LocalDateTime.now()); //校驗(yàn)數(shù)據(jù)(這個(gè)步驟主要是為了打印日志,可以省略) checkDataList(allTasks); //通過校驗(yàn)的數(shù)據(jù)執(zhí)行定時(shí)任務(wù) int count = 0; if(allTasks.size()>0) { for (int i = 0; i < allTasks.size(); i++) { try { scheduledTaskRegistrar.addTriggerTask(getRunnable(allTasks.get(i)), getTrigger(allTasks.get(i))); count++; } catch (Exception e) { log.error("定時(shí)任務(wù)啟動錯(cuò)誤:" + allTasks.get(i).getClassName() + ";" + allTasks.get(i).getMethodName() + ";" + e.getMessage()); } } } log.info("定時(shí)任務(wù)實(shí)際啟動數(shù)量="+count+"; time="+LocalDateTime.now()); } private static Trigger getTrigger(HkSysTask task){ return new Trigger() { @Override public Date nextExecutionTime(TriggerContext triggerContext) { //將Cron 0/1 * * * * ? 輸入取得下一次執(zhí)行的時(shí)間 CronTrigger trigger = new CronTrigger(task.getTaskCron()); Date nextExec = trigger.nextExecutionTime(triggerContext); return nextExec; } }; } private static Runnable getRunnable(HkSysTask task){ return new Runnable() { @Override public void run() { Class<?> clazz; try { clazz = Class.forName(task.getClassName()); String className = lowerFirstCapse(clazz.getSimpleName()); Object bean = SpringUtil.getBean(className); Method method = ReflectionUtils.findMethod(bean.getClass(), task.getMethodName()); ReflectionUtils.invokeMethod(method, bean); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }; } private List<HkSysTask> checkDataList(List<HkSysTask> list) { String errMsg=""; for(int i=0;i<list.size();i++){ if(!checkOneData(list.get(i)).equalsIgnoreCase("success")){ errMsg+=list.get(i).getTaskName()+";"; list.remove(list.get(i)); i--; }; } if(!StringUtils.isBlank(errMsg)){ errMsg="未啟動的任務(wù):"+errMsg; log.error(errMsg); } return list; } private String checkOneData(HkSysTask task){ String result="success"; Class clazz= null; try { clazz = Class.forName(task.getClassName()); //String className = lowerFirstCapse(clazz.getSimpleName()); Object obj =SpringUtil.getBean(clazz); Method method = obj.getClass().getMethod(task.getMethodName(),null); String cron=task.getTaskCron(); if(StringUtils.isBlank(cron)){ result="定時(shí)任務(wù)啟動錯(cuò)誤,無cron:"+task.getTaskName(); log.error(result); } } catch (ClassNotFoundException e) { result="定時(shí)任務(wù)啟動錯(cuò)誤,找不到類:"+task.getClassName()+ e.getMessage(); log.error(result); } catch (NoSuchMethodException e) { result="定時(shí)任務(wù)啟動錯(cuò)誤,找不到方法,方法必須是public:"+task.getClassName()+";"+task.getMethodName()+";"+ e.getMessage(); log.error(result); } catch (Exception e) { log.error(e.getMessage()); } return result; } /** * 轉(zhuǎn)換首字母小寫 * * @param str * @return */ public static String lowerFirstCapse(String str) { char[] chars = str.toCharArray(); chars[0] += 32; return String.valueOf(chars); } /** * 啟動定時(shí)任務(wù) * @param task * @param */ public static void start(HkSysTask task){ ScheduledFuture<?> scheduledFuture = threadPoolTaskScheduler.schedule(getRunnable(task),getTrigger(task)); scheduledFutureMap.put(task.getTaskUuid(),scheduledFuture); log.info("啟動定時(shí)任務(wù)" + task.getId() ); } /** * 取消定時(shí)任務(wù) * @param task */ public static void cancel(HkSysTask task){ ScheduledFuture<?> scheduledFuture = scheduledFutureMap.get(task.getId()); if(scheduledFuture != null && !scheduledFuture.isCancelled()){ scheduledFuture.cancel(Boolean.FALSE); } scheduledFutureMap.remove(task.getId()); log.info("取消定時(shí)任務(wù)" + task.getId() ); } /** * 編輯 * @param task * @param */ public static void reset(HkSysTask task){ log.info("修改定時(shí)任務(wù)開始" + task.getId() ); cancel(task); start(task); log.info("修改定時(shí)任務(wù)結(jié)束" + task.getId()); } }
4、定時(shí)執(zhí)行的測試類
...... public void test(){ iHkUserService.userTaskRun(); } ......
5、console輸出的日志
“如何實(shí)現(xiàn)集成定時(shí)任務(wù)SchedulingConfigurer”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
新聞標(biāo)題:如何實(shí)現(xiàn)集成定時(shí)任務(wù)SchedulingConfigurer
文章位置:http://jinyejixie.com/article26/ghhecg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、小程序開發(fā)、網(wǎng)站維護(hù)、企業(yè)網(wǎng)站制作、品牌網(wǎng)站制作、軟件開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)