扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
本篇内容介绍了“如何实现集成定时任务SchedulingConfigurer”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
成都创新互联公司自2013年起,先为桓仁等服务建站,桓仁等地企业,进行企业商务咨询服务。为桓仁企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
背景:
项目需要启动一个定时执行的任务,该任务的执行可以随时停止执行,要求在数据库配置执行规律。
调研:使用scheduling定时任务与springboot集成;
实例:
第一步:创建一个数据表,保存执行的任务
/*DDL 信息*/------------ CREATE TABLE `hk_sys_task` ( `id` bigint(21) NOT NULL AUTO_INCREMENT COMMENT '主键', `task_uuid` varchar(50) DEFAULT NULL COMMENT '任务UUID', `task_name` varchar(50) DEFAULT NULL COMMENT '任务名称', `task_cron` varchar(50) DEFAULT NULL COMMENT '任务定时表达式', `class_name` varchar(100) DEFAULT NULL COMMENT '任务类', `method_name` varchar(100) DEFAULT NULL COMMENT '任务方法', `task_type` int(1) DEFAULT NULL COMMENT '任务类型', `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、创建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配置成功,在普通类可以通过调用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 staticT getBean(Class clazz){ return getApplicationContext().getBean(clazz); } //通过name,以及Clazz返回指定的Bean public static T getBean(String name,Class clazz){ return getApplicationContext().getBean(name, clazz); } }
3、配置执行任务的类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> scheduledFutureMap = new HashMap<>(); //从数据库里取得所有要执行的定时任务 private List getAllTasks() { LambdaQueryWrapper 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 allTasks = getAllTasks(); log.info("定时任务启动,预计启动任务数量={},; time={}",allTasks.size(),LocalDateTime.now()); //校验数据(这个步骤主要是为了打印日志,可以省略) checkDataList(allTasks); //通过校验的数据执行定时任务 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("定时任务启动错误:" + allTasks.get(i).getClassName() + ";" + allTasks.get(i).getMethodName() + ";" + e.getMessage()); } } } log.info("定时任务实际启动数量="+count+"; time="+LocalDateTime.now()); } private static Trigger getTrigger(HkSysTask task){ return new Trigger() { @Override public Date nextExecutionTime(TriggerContext triggerContext) { //将Cron 0/1 * * * * ? 输入取得下一次执行的时间 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 checkDataList(List list) { String errMsg=""; for(int i=0;i scheduledFuture = threadPoolTaskScheduler.schedule(getRunnable(task),getTrigger(task)); scheduledFutureMap.put(task.getTaskUuid(),scheduledFuture); log.info("启动定时任务" + task.getId() ); } /** * 取消定时任务 * @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("取消定时任务" + task.getId() ); } /** * 编辑 * @param task * @param */ public static void reset(HkSysTask task){ log.info("修改定时任务开始" + task.getId() ); cancel(task); start(task); log.info("修改定时任务结束" + task.getId()); } }
4、定时执行的测试类
...... public void test(){ iHkUserService.userTaskRun(); } ......
5、console输出的日志
“如何实现集成定时任务SchedulingConfigurer”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流