一尘不染

如何停止使用@Scheduled批注启动的计划任务?

java

我已经使用Spring Framework的@Scheduled注释创建了一个简单的计划任务。

 @Scheduled(fixedRate = 2000)
 public void doSomething() {}

现在,当不再需要时,我想停止此任务。

我知道在此方法开始时可能有一种方法可以检查一个条件标志,但这不会停止执行此方法。

Spring提供了什么来停止@Scheduled任务?


阅读 309

收藏
2020-09-08

共1个答案

一尘不染

选项1:使用后处理器

为应停止调度的bean
提供ScheduledAnnotationBeanPostProcessor并显式调用postProcessBeforeDestruction(Object bean, String beanName)

选项2:维护目标豆与其未来的映射

private final Map<Object, ScheduledFuture<?>> scheduledTasks =
        new IdentityHashMap<>();

@Scheduled(fixedRate = 2000)
public void fixedRateJob() {
    System.out.println("Something to be done every 2 secs");
}

@Bean
public TaskScheduler poolScheduler() {
    return new CustomTaskScheduler();
}

class CustomTaskScheduler extends ThreadPoolTaskScheduler {

    @Override
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long period) {
        ScheduledFuture<?> future = super.scheduleAtFixedRate(task, period);

        ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task;
        scheduledTasks.put(runnable.getTarget(), future);

        return future;
    }

    @Override
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Date startTime, long period) {
        ScheduledFuture<?> future = super.scheduleAtFixedRate(task, startTime, period);

        ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task;
        scheduledTasks.put(runnable.getTarget(), future);

        return future;
    }
}

当必须停止对bean的调度时,可以查找该映射以获取对应的映射Future并显式取消它。

2020-09-08