|
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