I have created a simple scheduled task using Spring Framework’s @Scheduled
annotation.
@Scheduled(fixedRate = 2000) public void doSomething() {}
Now I want to stop this task, when no longer needed.
I know there could be one alternative to check one conditional flag at the start of this method, but this will not stop execution of this method.
Is there anything Spring provides to stop @Scheduled
task ?
Advertisement
Answer
Option 1: Using a post processor
Supply ScheduledAnnotationBeanPostProcessor
and explicitly invoke postProcessBeforeDestruction(Object bean, String beanName)
, for the bean whose scheduling should be stopped.
Option 2: Maintaining a map of target beans to its Future
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; } }
When the scheduling for a bean has to be stopped, you can lookup the map to get the corresponding Future
to it and explicitly cancel it.