多个类实现SchedulingConfigurer,不执行定时任务

在Springboot中,当多个类同时实现SchedulingConfigurer接口时,导致定时任务不执行或者部分不执行的原因是:
在Springboot中ScheduledTaskRegistrar 是一个共享对象,多个类在 configureTasks 方法中修改它时,可能会相互覆盖对方的任务配置。
为什么会覆盖对方的注册任务呢?
是因为如下代码,在多个类中同时执行了:

taskRegistrar.setTriggerTasks(triggerTasks);

导致定时任务被覆盖。

解决方式:将上面代码改成如下即可:

taskRegistrar.addTriggerTask(new TriggerTask(new TaskRunnable(task), new TaskTrigger(task)));

ScheduledTaskRegistrar类中,taskRegistrar.setTriggerTasks(triggerTasks);taskRegistrar.addTriggerTask(new TaskRunnable(task), new TaskTrigger(task));重点区别在于,setTriggerTasks()每次设置时都会重新创建一个list,而addTriggerTask()会重新判断,如果为空,才重新创建

// 在org.springframework.scheduling.config.ScheduledTaskRegistrar 中

public void setTriggerTasks(Map<Runnable, Trigger> triggerTasks) {
        // 每次都会重新new一个新的对象
        this.triggerTasks = new ArrayList();
        triggerTasks.forEach((task, trigger) -> {
            this.addTriggerTask(new TriggerTask(task, trigger));
        });
    }

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);
 }

定时任务实现代码

@Component
public class TaskSchedule implements SchedulingConfigurer{
    final TaskService taskService;

    public TaskSchedule(TaskService taskService) {
        this.taskService = taskService;
    }

    private void registrarTasks(ScheduledTaskRegistrar taskRegistrar) {
        // Map<Runnable, Trigger> triggerTasks = new HashMap<>();
        Filterable<Task> filterable = new Filterable<>();
        Map<String, Object> filter = Maps.newHashMap();
        filter.put("execService", "task-api");
        filterable.setFilter(filter);
        List<Task> taskConfigs = taskService.list(filterable);
        for (Task task : taskConfigs) {
            if (StringUtils.isBlank(task.getCron()))
                continue;

            if (task.getDeleted())
                continue;

            if (task.getStatus() == 0)
                continue;

            // triggerTasks.put(new TaskRunnable(task), new TaskTrigger(task));
            
            // 注册任务
            taskRegistrar.addTriggerTask(new TaskRunnable(task), new TaskTrigger(task));
        }
        // 重新设置任务 会清空triggerTasks中原来的任务
        // taskRegistrar.setTriggerTasks(triggerTasks);
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        this.registrarTasks(taskRegistrar);
    }
}

class TaskTrigger implements Trigger {
    Task task;

    public TaskTrigger(Task task) {
        this.task = task;
    }

    @Override
    public Date nextExecutionTime(TriggerContext triggerContext) {
        CronTrigger trigger = new CronTrigger(task.getCron());
        Date lastTime = triggerContext.lastScheduledExecutionTime();
        Date nextDate = trigger.nextExecutionTime(triggerContext);
        System.out.println(String.format("Task :%s Last Date:%s Next Date:%s ...", task.getId(), DateUtil.format(lastTime), DateUtil.format(nextDate)));
        return nextDate;
    }
}

class TaskRunnable implements Runnable {
    Task task;
    public TaskRunnable(Task task) {
        this.task = task;
    }
    @Override
    public void run() {
        System.out.println("执行定时任务、、、、、、");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值