美文网首页
SpringBoot动态定时任务

SpringBoot动态定时任务

作者: 一觉睡到丶小时候 | 来源:发表于2021-03-12 14:50 被阅读0次

    其实SchedulingConfigurer实现方法很简单,只需要实现SchedulingConfigurer并重写configureTasks方法,在启动类必须加上@EnableScheduling注解即可。

    @Configuration
    @EnableScheduling
    @Slf4j
    public class RuleTask implements SchedulingConfigurer {
    
        private volatile ScheduledTaskRegistrar registrar;
        private ConcurrentHashMap<Long, ScheduledFuture<?>> scheduledFutures = new ConcurrentHashMap<>();
        private ConcurrentHashMap<Long, CronTask> cronTasks = new ConcurrentHashMap<>();
    
        @Override
        public void configureTasks(ScheduledTaskRegistrar registrar) {
            registrar.setScheduler(Executors.newScheduledThreadPool(30));
            this.registrar = registrar;
        }
    
        /**
         * 刷新任务
         * cronList是数据库查出来的定时任务列表
         * @param ruleList
         */
        public void refresh(List<WarCron> cronList) {
            //取消已经删除的任务
            Set<Long> cronIds = scheduledFutures.keySet();
            for (Long cronId : cronIds) {
                if (!exists(cronList, cronId)) {
                    scheduledFutures.get(cronId).cancel(false);
                }
            }
            if (cronList != null) {
                for (WarCron warCron : cronList) {
                    String expression = warCron.getCron();
                    //定时任务已存在且表达式未发生变化时跳过
                    if (scheduledFutures.containsKey(warCron.getCronId()) && cronTasks.get(warCron.getCronId()).getExpression().equals(expression)) {
                        continue;
                    }
                    //如果执行时间发生了变化,则取消当前的定时任务
                    if (scheduledFutures.containsKey(warCron.getCronId())) {
                        scheduledFutures.get(warCron.getCronId()).cancel(false);
                        scheduledFutures.remove(warCron.getCronId());
                        cronTasks.remove(warCron.getCronId());
                    }
                    CronTask task = new CronTask(
                            new Runnable() {
                                @Override
                                public void run() {
                                    System.out.println("------------定时任务--------------");
                                }
                            }, warCron.getCron()
                    );
                    ScheduledFuture<?> future = registrar.getScheduler().schedule(task.getRunnable(), task.getTrigger());
                    cronTasks.put(warCron.getCronId(), task);
                    scheduledFutures.put(warCron.getCronId(), future);
                }
            }
        }
    
       /**
         * 判断是否有该任务
         *
         * @param warCronList
         * @param cronId
         * @return
         */
        private boolean exists(List<WarCron> warCronList, Long cronId) {
            for (WarCron warCron : warCronList) {
                if (cronId.equals(warCron.getCronId())) {
                    return true;
                }
            }
            return false;
        }
    }
    

    每次新增编辑删除数据库中的任务时都需刷新下任务 以达到任务的动态变化
    启动boot时也需执行refresh方法;

    /**
     * @Author: pandar
     * @Date: 2021/3/12 0012 上午 11:57
     * @Description:  项目启动后刷新定时任务
     */
    @Component
    public class ApplicationRunnerConfig implements ApplicationRunner {
    
        @Autowired
        private RuleTask ruleTask;
        @Autowired
        private WarCronService warCronService;
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
            List<WarCron> warCronList = warCronService.selectWarCronAll();
            ruleTask.refresh(ruleList);
        }
    }
    

    数据库表结构


    数据库.png

    相关文章

      网友评论

          本文标题:SpringBoot动态定时任务

          本文链接:https://www.haomeiwen.com/subject/dkdzqltx.html