Skip to content

Commit 0f73a69

Browse files
committed
AbstractApplicationContext resets local listeners to pre-refresh state
Closes gh-22325
1 parent e962677 commit 0f73a69

File tree

1 file changed

+28
-6
lines changed

1 file changed

+28
-6
lines changed

spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -212,7 +212,11 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
212212
/** Statically specified listeners. */
213213
private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
214214

215-
/** ApplicationEvents published early. */
215+
/** Local listeners registered before refresh. */
216+
@Nullable
217+
private Set<ApplicationListener<?>> earlyApplicationListeners;
218+
219+
/** ApplicationEvents published before the multicaster setup. */
216220
@Nullable
217221
private Set<ApplicationEvent> earlyApplicationEvents;
218222

@@ -483,7 +487,6 @@ public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor)
483487
this.beanFactoryPostProcessors.add(postProcessor);
484488
}
485489

486-
487490
/**
488491
* Return the list of BeanFactoryPostProcessors that will get applied
489492
* to the internal BeanFactory.
@@ -578,6 +581,7 @@ public void refresh() throws BeansException, IllegalStateException {
578581
* active flag as well as performing any initialization of property sources.
579582
*/
580583
protected void prepareRefresh() {
584+
// Switch to active.
581585
this.startupDate = System.currentTimeMillis();
582586
this.closed.set(false);
583587
this.active.set(true);
@@ -591,13 +595,23 @@ protected void prepareRefresh() {
591595
}
592596
}
593597

594-
// Initialize any placeholder property sources in the context environment
598+
// Initialize any placeholder property sources in the context environment.
595599
initPropertySources();
596600

597-
// Validate that all properties marked as required are resolvable
601+
// Validate that all properties marked as required are resolvable:
598602
// see ConfigurablePropertyResolver#setRequiredProperties
599603
getEnvironment().validateRequiredProperties();
600604

605+
// Store pre-refresh ApplicationListeners...
606+
if (this.earlyApplicationListeners == null) {
607+
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
608+
}
609+
else {
610+
// Reset local application listeners to pre-refresh state.
611+
this.applicationListeners.clear();
612+
this.applicationListeners.addAll(this.earlyApplicationListeners);
613+
}
614+
601615
// Allow for the collection of early ApplicationEvents,
602616
// to be published once the multicaster is available...
603617
this.earlyApplicationEvents = new LinkedHashSet<>();
@@ -982,6 +996,7 @@ public void close() {
982996
* @see #registerShutdownHook()
983997
*/
984998
protected void doClose() {
999+
// Check whether an actual close attempt is necessary...
9851000
if (this.active.get() && this.closed.compareAndSet(false, true)) {
9861001
if (logger.isDebugEnabled()) {
9871002
logger.debug("Closing " + this);
@@ -1016,6 +1031,13 @@ protected void doClose() {
10161031
// Let subclasses do some final clean-up if they wish...
10171032
onClose();
10181033

1034+
// Reset local application listeners to pre-refresh state.
1035+
if (this.earlyApplicationListeners != null) {
1036+
this.applicationListeners.clear();
1037+
this.applicationListeners.addAll(this.earlyApplicationListeners);
1038+
}
1039+
1040+
// Switch to inactive.
10191041
this.active.set(false);
10201042
}
10211043
}
@@ -1302,7 +1324,7 @@ private MessageSource getMessageSource() throws IllegalStateException {
13021324
@Nullable
13031325
protected MessageSource getInternalParentMessageSource() {
13041326
return (getParent() instanceof AbstractApplicationContext ?
1305-
((AbstractApplicationContext) getParent()).messageSource : getParent());
1327+
((AbstractApplicationContext) getParent()).messageSource : getParent());
13061328
}
13071329

13081330

0 commit comments

Comments
 (0)