如何在调用 JVM 的关闭钩子之前关闭 @SpringBootTest 上下文(一次,在所有 JUnit 测试之后)

How to close the @SpringBootTest context before JVM's shutdown hook is called (once, after all JUnit tests)

Q. 如何在 JUnit 5 停止之前关闭 Spring 引导上下文,它是通过使用 @SpringBootTest 注释测试 class 创建的JVM(调用添加了 addShutdownHook() 的钩子) ?


示例:
假设像这样的 bean

@Component
public class SomeBean implements DisposableBean {

    public SomeBean() {
        var hook = new Thread(() -> System.out.println("Shutdown Hook called"));
        Runtime.getRuntime().addShutdownHook(hook);
    }

    @Override
    public void destroy() {
        System.out.println("Destroy called");
    }
}

和一个像这样的简单 Junit 5 测试:

@SpringBootTest
class TestJvmShutdownHookApplicationTests {

    @Test
    void contextLoads() {
    }

}

如何在 JVM 关闭挂钩之前调用 destroy()

2021-02-18 13:54:24.540  INFO 18928 --- [           main] .a.t.TestJvmShutdownHookApplicationTests : Started TestJvmShutdownHookApplicationTests in 2.378 seconds (JVM running for 3.687)
Shutdown Hook called
2021-02-18 13:54:24.863  INFO 18928 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
Destroy called

背景 it.ozimov:embedded-redis 添加 JVM 关闭挂钩并在 bean redisConnectionFactory (Lettuce) 被销毁之前关闭 Redis 服务器。

目前没有实现此功能的内置支持。

有关详细信息,请参阅 Spring 框架问题跟踪器中的 Close all ApplicationContexts in the TestContext framework after all tests have been executed 问题。

目前,正确关闭由 Spring TestContext Framework 缓存的 ApplicationContext 的唯一方法是通过 @DirtiesContext 或自定义 TestExecutionListener 调用 TestContext#markApplicationContextDirty(...)