|
51 | 51 | import org.springframework.context.ApplicationContextAware; |
52 | 52 | import org.springframework.context.ApplicationListener; |
53 | 53 | import org.springframework.context.EmbeddedValueResolverAware; |
| 54 | +import org.springframework.context.event.ApplicationContextEvent; |
| 55 | +import org.springframework.context.event.ContextClosedEvent; |
54 | 56 | import org.springframework.context.event.ContextRefreshedEvent; |
55 | 57 | import org.springframework.core.MethodIntrospector; |
56 | 58 | import org.springframework.core.Ordered; |
|
108 | 110 | public class ScheduledAnnotationBeanPostProcessor |
109 | 111 | implements ScheduledTaskHolder, MergedBeanDefinitionPostProcessor, DestructionAwareBeanPostProcessor, |
110 | 112 | Ordered, EmbeddedValueResolverAware, BeanNameAware, BeanFactoryAware, ApplicationContextAware, |
111 | | - SmartInitializingSingleton, ApplicationListener<ContextRefreshedEvent>, DisposableBean { |
| 113 | + SmartInitializingSingleton, DisposableBean, ApplicationListener<ApplicationContextEvent> { |
112 | 114 |
|
113 | 115 | /** |
114 | 116 | * The default name of the {@link TaskScheduler} bean to pick up: {@value}. |
@@ -239,16 +241,6 @@ public void afterSingletonsInstantiated() { |
239 | 241 | } |
240 | 242 | } |
241 | 243 |
|
242 | | - @Override |
243 | | - public void onApplicationEvent(ContextRefreshedEvent event) { |
244 | | - if (event.getApplicationContext() == this.applicationContext) { |
245 | | - // Running in an ApplicationContext -> register tasks this late... |
246 | | - // giving other ContextRefreshedEvent listeners a chance to perform |
247 | | - // their work at the same time (e.g. Spring Batch's job registration). |
248 | | - finishRegistration(); |
249 | | - } |
250 | | - } |
251 | | - |
252 | 244 | private void finishRegistration() { |
253 | 245 | if (this.scheduler != null) { |
254 | 246 | this.registrar.setScheduler(this.scheduler); |
@@ -645,4 +637,33 @@ public void destroy() { |
645 | 637 | } |
646 | 638 | } |
647 | 639 |
|
| 640 | + |
| 641 | + /** |
| 642 | + * Reacts to {@link ContextRefreshedEvent} as well as {@link ContextClosedEvent}: |
| 643 | + * performing {@link #finishRegistration()} and early cancelling of scheduled tasks, |
| 644 | + * respectively. |
| 645 | + */ |
| 646 | + @Override |
| 647 | + public void onApplicationEvent(ApplicationContextEvent event) { |
| 648 | + if (event.getApplicationContext() == this.applicationContext) { |
| 649 | + if (event instanceof ContextRefreshedEvent) { |
| 650 | + // Running in an ApplicationContext -> register tasks this late... |
| 651 | + // giving other ContextRefreshedEvent listeners a chance to perform |
| 652 | + // their work at the same time (e.g. Spring Batch's job registration). |
| 653 | + finishRegistration(); |
| 654 | + } |
| 655 | + else if (event instanceof ContextClosedEvent) { |
| 656 | + synchronized (this.scheduledTasks) { |
| 657 | + Collection<Set<ScheduledTask>> allTasks = this.scheduledTasks.values(); |
| 658 | + for (Set<ScheduledTask> tasks : allTasks) { |
| 659 | + for (ScheduledTask task : tasks) { |
| 660 | + // At this early point, let in-progress tasks complete still |
| 661 | + task.cancel(false); |
| 662 | + } |
| 663 | + } |
| 664 | + } |
| 665 | + } |
| 666 | + } |
| 667 | + } |
| 668 | + |
648 | 669 | } |
0 commit comments