Skip to content

Commit 495665a

Browse files
committed
Use reverse order for shutdown hooks
Refine `SpringApplicationShutdownHook` so that shutdown happens in reverse order to registration. See gh-43430
1 parent 4763123 commit 495665a

File tree

2 files changed

+8
-5
lines changed

2 files changed

+8
-5
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplicationShutdownHook.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616

1717
package org.springframework.boot;
1818

19+
import java.util.ArrayList;
1920
import java.util.Collections;
2021
import java.util.LinkedHashSet;
22+
import java.util.List;
2123
import java.util.Set;
2224
import java.util.WeakHashMap;
2325
import java.util.concurrent.TimeUnit;
@@ -103,12 +105,13 @@ void deregisterFailedApplicationContext(ConfigurableApplicationContext applicati
103105
public void run() {
104106
Set<ConfigurableApplicationContext> contexts;
105107
Set<ConfigurableApplicationContext> closedContexts;
106-
Set<Handler> handlers;
108+
List<Handler> handlers;
107109
synchronized (SpringApplicationShutdownHook.class) {
108110
this.inProgress = true;
109111
contexts = new LinkedHashSet<>(this.contexts);
110112
closedContexts = new LinkedHashSet<>(this.closedContexts);
111-
handlers = new LinkedHashSet<>(this.handlers.getActions());
113+
handlers = new ArrayList<>(this.handlers.getActions());
114+
Collections.reverse(handlers);
112115
}
113116
contexts.forEach(this::closeAndWait);
114117
closedContexts.forEach(this::closeAndWait);

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationShutdownHookTests.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ void deregistersFailedContext() {
207207
}
208208

209209
@Test
210-
void handlersRunInDeterministicOrder() {
210+
void handlersRunInDeterministicOrderFromLastRegisteredToFirst() {
211211
TestSpringApplicationShutdownHook shutdownHook = new TestSpringApplicationShutdownHook();
212212
Runnable r1 = mock(Runnable.class);
213213
Runnable r2 = mock(Runnable.class);
@@ -217,9 +217,9 @@ void handlersRunInDeterministicOrder() {
217217
shutdownHook.getHandlers().add(r3);
218218
shutdownHook.run();
219219
InOrder ordered = inOrder(r1, r2, r3);
220-
ordered.verify(r2).run();
221-
ordered.verify(r1).run();
222220
ordered.verify(r3).run();
221+
ordered.verify(r1).run();
222+
ordered.verify(r2).run();
223223
ordered.verifyNoMoreInteractions();
224224
}
225225

0 commit comments

Comments
 (0)