Skip to content

Commit

Permalink
ContextClosedEvent triggers early cancelling of scheduled tasks
Browse files Browse the repository at this point in the history
Closes gh-24629
See gh-27090
  • Loading branch information
jhoeller committed Jul 11, 2023
1 parent 57ed5bf commit e048b09
Showing 1 changed file with 32 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.event.ApplicationContextEvent;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.MethodIntrospector;
import org.springframework.core.Ordered;
Expand Down Expand Up @@ -108,7 +110,7 @@
public class ScheduledAnnotationBeanPostProcessor
implements ScheduledTaskHolder, MergedBeanDefinitionPostProcessor, DestructionAwareBeanPostProcessor,
Ordered, EmbeddedValueResolverAware, BeanNameAware, BeanFactoryAware, ApplicationContextAware,
SmartInitializingSingleton, ApplicationListener<ContextRefreshedEvent>, DisposableBean {
SmartInitializingSingleton, DisposableBean, ApplicationListener<ApplicationContextEvent> {

/**
* The default name of the {@link TaskScheduler} bean to pick up: {@value}.
Expand Down Expand Up @@ -239,16 +241,6 @@ public void afterSingletonsInstantiated() {
}
}

@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (event.getApplicationContext() == this.applicationContext) {
// Running in an ApplicationContext -> register tasks this late...
// giving other ContextRefreshedEvent listeners a chance to perform
// their work at the same time (e.g. Spring Batch's job registration).
finishRegistration();
}
}

private void finishRegistration() {
if (this.scheduler != null) {
this.registrar.setScheduler(this.scheduler);
Expand Down Expand Up @@ -645,4 +637,33 @@ public void destroy() {
}
}


/**
* Reacts to {@link ContextRefreshedEvent} as well as {@link ContextClosedEvent}:
* performing {@link #finishRegistration()} and early cancelling of scheduled tasks,
* respectively.
*/
@Override
public void onApplicationEvent(ApplicationContextEvent event) {
if (event.getApplicationContext() == this.applicationContext) {
if (event instanceof ContextRefreshedEvent) {
// Running in an ApplicationContext -> register tasks this late...
// giving other ContextRefreshedEvent listeners a chance to perform
// their work at the same time (e.g. Spring Batch's job registration).
finishRegistration();
}
else if (event instanceof ContextClosedEvent) {
synchronized (this.scheduledTasks) {
Collection<Set<ScheduledTask>> allTasks = this.scheduledTasks.values();
for (Set<ScheduledTask> tasks : allTasks) {
for (ScheduledTask task : tasks) {
// At this early point, let in-progress tasks complete still
task.cancel(false);
}
}
}
}
}
}

}

0 comments on commit e048b09

Please sign in to comment.