什么时候依赖 Spring 的 @PreDestroy 是安全的?

use*_*098 5 spring spring-annotations spring-boot

根据Spring 的文档,我添加了一个关闭钩子:

SpringApplication app = new SpringApplication(App.class);
DefaultProfileUtil.addDefaultProfile(app);
appContext = app.run(args);
appContext.registerShutdownHook();
Run Code Online (Sandbox Code Playgroud)

但是,@PreDestroy如果应用程序在启动后进行编辑,则不会调用该方法kill

import org.springframework.stereotype.Service;
import javax.annotation.PreDestroy;
import javax.annotation.PostConstruct;
@Service
public class Processor {
  public Processor() {
    ...
  }
  @PostConstruct
  public void init() {
    System.err.println("processor started");
  }
  //not called reliably
  @PreDestroy
  public void shutdown() {
    System.err.println("starting shutdown");
    try {Thread.sleep(1000*10);} catch (InterruptedException e) {e.printStackTrace();}
    System.err.println("shutdown completed properly");
  }
}
Run Code Online (Sandbox Code Playgroud)

我所看到的只是processor started...

processor started

^C
Run Code Online (Sandbox Code Playgroud)

如果我等待至少 30 秒让 spring 完成启动,然后执行kill该过程,那么@PreDestroy带注释的函数就会被调用。

processor started
[...]
2018-12-26 17:01:09.050  INFO 31398 --- [  restartedMain] c.App                                    : Started App in 67.555 seconds (JVM running for 69.338)
2018-12-26 17:01:09.111  INFO 31398 --- [  restartedMain] c.App                                    :
----------------------------------------------------------
        Application 'App' is running! Access URLs:
        Local:          http://localhost:8081
        External:       http://10.10.7.29:8081
        Profile(s):     [dev]
----------------------------------------------------------
2018-12-26 17:01:09.111  INFO 31398 --- [  restartedMain] c.app                                    :
----------------------------------------------------------
^Cstarting shutdown
shutdown completed properly
Run Code Online (Sandbox Code Playgroud)

如何确定何时可以安全地依赖所有@PreDestroy带注释的函数的调用?

我知道如何向 JVM 注册关闭钩子,这就是我目前正在做的事情,但在我看来@PreDestroy应该这样做。

通过“安全依赖”,我假设正常的关闭顺序(即由SIGTERM或请求SIGINT),而不是断电和终止进程等。