I have created a simple scheduled task using Spring Framework\'s @Scheduled annotation.
@Scheduled(fixedRate = 2000)
public void doSomething() {}
Here is an example where we can stop , start , and list also all the scheduled running tasks:
@RestController
@RequestMapping("/test")
public class TestController {
private static final String SCHEDULED_TASKS = "scheduledTasks";
@Autowired
private ScheduledAnnotationBeanPostProcessor postProcessor;
@Autowired
private ScheduledTasks scheduledTasks;
@Autowired
private ObjectMapper objectMapper;
@GetMapping(value = "/stopScheduler")
public String stopSchedule(){
postProcessor.postProcessBeforeDestruction(scheduledTasks, SCHEDULED_TASKS);
return "OK";
}
@GetMapping(value = "/startScheduler")
public String startSchedule(){
postProcessor.postProcessAfterInitialization(scheduledTasks, SCHEDULED_TASKS);
return "OK";
}
@GetMapping(value = "/listScheduler")
public String listSchedules() throws JsonProcessingException{
Set<ScheduledTask> setTasks = postProcessor.getScheduledTasks();
if(!setTasks.isEmpty()){
return objectMapper.writeValueAsString(setTasks);
}else{
return "No running tasks !";
}
}
}
When spring process Scheduled
, it will iterate each method annotated this annotation and organize tasks by beans as the following source shows:
private final Map<Object, Set<ScheduledTask>> scheduledTasks =
new IdentityHashMap<Object, Set<ScheduledTask>>(16);
If you just want to cancel the a repeated scheduled task, you can just do like following (here is a runnable demo in my repo):
@Autowired
private ScheduledAnnotationBeanPostProcessor postProcessor;
@Autowired
private TestSchedule testSchedule;
public void later() {
postProcessor.postProcessBeforeDestruction(test, "testSchedule");
}
It will find this beans's ScheduledTask
and cancel it one by one. What should be noticed is it will also stopping the current running method (as postProcessBeforeDestruction
source shows).
synchronized (this.scheduledTasks) {
tasks = this.scheduledTasks.remove(bean); // remove from future running
}
if (tasks != null) {
for (ScheduledTask task : tasks) {
task.cancel(); // cancel current running method
}
}