springboot中@scheduled的开关机制(针对全局定时任务)

在SpringBoot中,利用@scheduled实现定时任务时,如何实现在不同环境中控制所有定时任务的开启或关闭?本文介绍一种解决方案,通过了解ScheduledTaskRegistrar类,清空扫描的定时任务类别,达到统一控制的效果。

 

 

目前遇到的问题:

我们可以在springboot中使用@scheduled注解来完成定时任务。我现在有两台机器部署同一个应用。

一台希望开启全部的定时器,另一台希望关闭全部定时器,考虑到上一篇博客

https://blog.csdn.net/qq_37826571/article/details/105097249)只能对一个定时任务进行开关,我不能把之前的定时任务都分离

出来一个个的改代码,太麻烦了,怎么办?

解决方案:

那就要从源头去解决,这里大家要了解ScheduledTaskRegistrar 这个类,我这里为了 大家方便,给大家展示出来这个类。

 

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.scheduling.config;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

public class ScheduledTaskRegistrar implements InitializingBean, DisposableBean {
    private TaskScheduler taskScheduler;
    private ScheduledExecutorService localExecutor;
    private List<TriggerTask> triggerTasks;
    private List<CronTask> cronTasks;
    private List<IntervalTask> fixedRateTasks;
    private List<IntervalTask> fixedDelayTasks;
    private final Map<Task, ScheduledTask> unresolvedTasks = new HashMap(16);
    private final Set<ScheduledTask> scheduledTasks = new LinkedHashSet(16);

    public ScheduledTaskRegistrar() {
    }

    public void setTaskScheduler(TaskScheduler taskScheduler) {
        Assert.notNull(taskScheduler, "TaskScheduler must not be null");
        this.taskScheduler = taskScheduler;
    }

    public void setScheduler(Object scheduler) {
        Assert.notNull(scheduler, "Scheduler object must not be null");
        if (scheduler instanceof TaskScheduler) {
            this.taskScheduler = (TaskScheduler)scheduler;
        } else {
            if (!(scheduler instanceof ScheduledExecutorService)) {
                throw new IllegalArgumentException("Unsupported scheduler type: " + scheduler.getClass());
            }

            this.taskScheduler = new ConcurrentTaskScheduler((ScheduledExecutorService)scheduler);
        }

    }

    public TaskScheduler getScheduler() {
        return this.taskScheduler;
    }

    public void setTriggerTasks(Map<Runnable, Trigger> triggerTasks) {
        this.triggerTasks = new ArrayList();
        Iterator var2 = triggerTasks.entrySet().iterator();

        while(var2.hasNext()) {
            Entry<Runnable, Trigger> task = (Entry)var2.next();
            this.addTriggerTask(new TriggerTask((Runnable)task.getKey(), (Trigger)task.getValue()));
        }

    }

    public void setTriggerTasksList(List<TriggerTask> triggerTasks) {
        this.triggerTasks = triggerTasks;
    }

    public List<TriggerTask> getTriggerTaskList() {
        return this.triggerTasks != null ? Collections.unmodifiableList(this.triggerTasks) : Collections.emptyList();
    }

    public void setCronTasks(Map<Runnable, String> cronTasks) {
        this.cronTasks = new ArrayList();
        Iterator var2 = cronTasks.entrySet().iterator();

        while(var2.hasNext()) {
            Entry<Runnable, String> task = (Entry)var2.next();
            this.addCronTask((Runnable)task.getKey(), (String)task.getValue());
        }

    }

    public void setCronTasksList(List<CronTask> cronTasks) {
        this.cronTasks = cronTasks;
    }

    public List<CronTask> getCronTaskList() {
        return this.cronTasks != null ? Collections.unmodifiableList(this.cronTasks) : Collections.emptyList();
    }

    public void setFixedRateTasks(Map<Runnable, Long> fixedRateTasks) {
        this.fixedRateTasks = new ArrayList();
        Iterator var2 = fixedRateTasks.entrySet().iterator();

        while(var2.hasNext()) {
            Entry<Runnable, Long> task = (Entry)var2.next();
            this.addFixedRateTask((Runnable)task.getKey(), (Long)task.getValue());
        }

    }

    public void setFixedRateTasksList(List<IntervalTask> fixedRateTasks) {
        this.fixedRateTasks = fixedRateTasks;
    }

    public List<IntervalTask> getFixedRateTaskList() {
        return this.fixedRateTasks != null ? Collections.unmodifiableList(this.fixedRateTasks) : Collections.emptyList();
    }

    public void setFixedDelayTasks(Map<Runnable, Long> fixedDelayTasks) {
        this.fixedDelayTasks = new ArrayList();
        Iterator var2 = fixedDelayTasks.entrySet().iterator();

        while(var2.hasNext()) {
            Entry<Runnable, Long> task = (Entry)var2.next();
            this.addFixedDelayTask((Runnable)task.getKey(), (Long)task.getValue());
        }

    }

    public void setFixedDelayTasksList(List<IntervalTask> fixedDelayTasks) {
        this.fixedDelayTasks = fixedDelayTasks;
    }

    public List<IntervalTask> getFixedDelayTaskList() {
        return this.fixedDelayTasks != null ? Collections.unmodifiableList(this.fixedDelayTasks) : Collections.emptyList();
    }

    public void addTriggerTask(Runnable task, Trigger trigger) {
        this.addTriggerTask(new TriggerTask(task, trigger));
    }

    public void addTriggerTask(TriggerTask task) {
        if (this.triggerTasks == null) {
            this.triggerTasks = new ArrayList();
        }

        this.triggerTasks.add(task);
    }

    public void addCronTask(Runnable task, String expression) {
        this.addCronTask(new CronTask(task, expression));
    }

    public void addCronTask(CronTask task) {
        if (this.cronTasks == null) {
            this.cronTasks = new ArrayList();
        }

        this.cronTasks.add(task);
    }

    public void addFixedRateTask(Runnable task, long interval) {
        this.addFixedRateTask(new IntervalTask(task, interval, 0L));
    }

    public void addFixedRateTask(IntervalTask task) {
        if (this.fixedRateTasks == null) {
            this.fixedRateTasks = new ArrayList();
        }

        this.fixedRateTasks.add(task);
    }

    public void addFixedDelayTask(Runnable task, long delay) {
        this.addFixedDelayTask(new IntervalTask(task, delay, 0L));
    }

    public void addFixedDelayTask(IntervalTask task) {
        if (this.fixedDelayTasks == null) {
            this.fixedDelayTasks = new ArrayList();
        }

        this.fixedDelayTasks.add(task);
    }

    public boolean hasTasks() {
        return !CollectionUtils.isEmpty(this.triggerTasks) || !CollectionUtils.isEmpty(this.cronTasks) || !CollectionUtils.isEmpty(this.fixedRateTasks) || !CollectionUtils.isEmpty(this.fixedDelayTasks);
    }

    public void afterPropertiesSet() {
        this.scheduleTasks();
    }

    protected void scheduleTasks() {
        if (this.taskScheduler == null) {
            this.localExecutor = Executors.newSingleThreadScheduledExecutor();
            this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
        }

        Iterator var1;
        if (this.triggerTasks != null) {
            var1 = this.triggerTasks.iterator();

            while(var1.hasNext()) {
                TriggerTask task = (TriggerTask)var1.next();
                this.addScheduledTask(this.scheduleTriggerTask(task));
            }
        }

        if (this.cronTasks != null) {
            var1 = this.cronTasks.iterator();

            while(var1.hasNext()) {
                CronTask task = (CronTask)var1.next();
                this.addScheduledTask(this.scheduleCronTask(task));
            }
        }

        IntervalTask task;
        if (this.fixedRateTasks != null) {
            var1 = this.fixedRateTasks.iterator();

            while(var1.hasNext()) {
                task = (IntervalTask)var1.next();
                this.addScheduledTask(this.scheduleFixedRateTask(task));
            }
        }

        if (this.fixedDelayTasks != null) {
            var1 = this.fixedDelayTasks.iterator();

            while(var1.hasNext()) {
                task = (IntervalTask)var1.next();
                this.addScheduledTask(this.scheduleFixedDelayTask(task));
            }
        }

    }

    private void addScheduledTask(ScheduledTask task) {
        if (task != null) {
            this.scheduledTasks.add(task);
        }

    }

    public ScheduledTask scheduleTriggerTask(TriggerTask task) {
        ScheduledTask scheduledTask = (ScheduledTask)this.unresolvedTasks.remove(task);
        boolean newTask = false;
        if (scheduledTask == null) {
            scheduledTask = new ScheduledTask();
            newTask = true;
        }

        if (this.taskScheduler != null) {
            scheduledTask.future = this.taskScheduler.schedule(task.getRunnable(), task.getTrigger());
        } else {
            this.addTriggerTask(task);
            this.unresolvedTasks.put(task, scheduledTask);
        }

        return newTask ? scheduledTask : null;
    }

    public ScheduledTask scheduleCronTask(CronTask task) {
        ScheduledTask scheduledTask = (ScheduledTask)this.unresolvedTasks.remove(task);
        boolean newTask = false;
        if (scheduledTask == null) {
            scheduledTask = new ScheduledTask();
            newTask = true;
        }

        if (this.taskScheduler != null) {
            scheduledTask.future = this.taskScheduler.schedule(task.getRunnable(), task.getTrigger());
        } else {
            this.addCronTask(task);
            this.unresolvedTasks.put(task, scheduledTask);
        }

        return newTask ? scheduledTask : null;
    }

    public ScheduledTask scheduleFixedRateTask(IntervalTask task) {
        ScheduledTask scheduledTask = (ScheduledTask)this.unresolvedTasks.remove(task);
        boolean newTask = false;
        if (scheduledTask == null) {
            scheduledTask = new ScheduledTask();
            newTask = true;
        }

        if (this.taskScheduler != null) {
            if (task.getInitialDelay() > 0L) {
                Date startTime = new Date(System.currentTimeMillis() + task.getInitialDelay());
                scheduledTask.future = this.taskScheduler.scheduleAtFixedRate(task.getRunnable(), startTime, task.getInterval());
            } else {
                scheduledTask.future = this.taskScheduler.scheduleAtFixedRate(task.getRunnable(), task.getInterval());
            }
        } else {
            this.addFixedRateTask(task);
            this.unresolvedTasks.put(task, scheduledTask);
        }

        return newTask ? scheduledTask : null;
    }

    public ScheduledTask scheduleFixedDelayTask(IntervalTask task) {
        ScheduledTask scheduledTask = (ScheduledTask)this.unresolvedTasks.remove(task);
        boolean newTask = false;
        if (scheduledTask == null) {
            scheduledTask = new ScheduledTask();
            newTask = true;
        }

        if (this.taskScheduler != null) {
            if (task.getInitialDelay() > 0L) {
                Date startTime = new Date(System.currentTimeMillis() + task.getInitialDelay());
                scheduledTask.future = this.taskScheduler.scheduleWithFixedDelay(task.getRunnable(), startTime, task.getInterval());
            } else {
                scheduledTask.future = this.taskScheduler.scheduleWithFixedDelay(task.getRunnable(), task.getInterval());
            }
        } else {
            this.addFixedDelayTask(task);
            this.unresolvedTasks.put(task, scheduledTask);
        }

        return newTask ? scheduledTask : null;
    }

    public void destroy() {
        Iterator var1 = this.scheduledTasks.iterator();

        while(var1.hasNext()) {
            ScheduledTask task = (ScheduledTask)var1.next();
            task.cancel();
        }

        if (this.localExecutor != null) {
            this.localExecutor.shutdownNow();
        }

    }
}

 

我们把扫描的几个类别的Task清空 就可以了。(这里要看@Schedule 注解里 你使用的是哪个类别的Task,如果只有Cron的 ,那就只删除CronTask就可以)

如下代码:

import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

import java.util.concurrent.Executor;

@Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer {

    @Value("${scheduling.enabled}")
    private boolean taskSwitch;

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        if(!taskSwitch){
            //清空扫描到的定时任务即可
            taskRegistrar.setTriggerTasks(Maps.newHashMap());
            taskRegistrar.setCronTasks(Maps.newHashMap());
            taskRegistrar.setFixedRateTasks(Maps.newHashMap());
            taskRegistrar.setFixedDelayTasks(Maps.newHashMap());
        }
        taskRegistrar.setScheduler(taskExecutor());
    }

    @Bean(destroyMethod = "shutdown")
    public Executor taskExecutor() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(10);
        taskScheduler.initialize();
        return taskScheduler;
    }
}

配置文件:

application.properties

# @Schedule 定时任务的开true/关false
scheduling.enabled=true

欢迎大家留言遇到的问题

如果大家觉得对这个操作的原理不是很理解,给大家推荐一个博客:

https://blog.csdn.net/a842699897/article/details/83790282

我就不写了,这个博客写的不错

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值