From 495665aec0cd5cbf27d1c0fdb3563669312122c2 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Tue, 17 Dec 2024 09:49:57 -0800 Subject: [PATCH] Use reverse order for shutdown hooks Refine `SpringApplicationShutdownHook` so that shutdown happens in reverse order to registration. See gh-43430 --- .../boot/SpringApplicationShutdownHook.java | 7 +++++-- .../boot/SpringApplicationShutdownHookTests.java | 6 +++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplicationShutdownHook.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplicationShutdownHook.java index 8e5e4ad3a34..433087a1bed 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplicationShutdownHook.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplicationShutdownHook.java @@ -16,8 +16,10 @@ package org.springframework.boot; +import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashSet; +import java.util.List; import java.util.Set; import java.util.WeakHashMap; import java.util.concurrent.TimeUnit; @@ -103,12 +105,13 @@ class SpringApplicationShutdownHook implements Runnable { public void run() { Set contexts; Set closedContexts; - Set handlers; + List handlers; synchronized (SpringApplicationShutdownHook.class) { this.inProgress = true; contexts = new LinkedHashSet<>(this.contexts); closedContexts = new LinkedHashSet<>(this.closedContexts); - handlers = new LinkedHashSet<>(this.handlers.getActions()); + handlers = new ArrayList<>(this.handlers.getActions()); + Collections.reverse(handlers); } contexts.forEach(this::closeAndWait); closedContexts.forEach(this::closeAndWait); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationShutdownHookTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationShutdownHookTests.java index 4d4d56947d7..b1854e25319 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationShutdownHookTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationShutdownHookTests.java @@ -207,7 +207,7 @@ class SpringApplicationShutdownHookTests { } @Test - void handlersRunInDeterministicOrder() { + void handlersRunInDeterministicOrderFromLastRegisteredToFirst() { TestSpringApplicationShutdownHook shutdownHook = new TestSpringApplicationShutdownHook(); Runnable r1 = mock(Runnable.class); Runnable r2 = mock(Runnable.class); @@ -217,9 +217,9 @@ class SpringApplicationShutdownHookTests { shutdownHook.getHandlers().add(r3); shutdownHook.run(); InOrder ordered = inOrder(r1, r2, r3); - ordered.verify(r2).run(); - ordered.verify(r1).run(); ordered.verify(r3).run(); + ordered.verify(r1).run(); + ordered.verify(r2).run(); ordered.verifyNoMoreInteractions(); }