运行SpringBootApplication PostConstruct和PreDestroy

我在运行docker容器中的spring应用程序时遇到了麻烦(spring和docker在我的环境中都有最新版本)。 我想为应用程序类创build一个健康的生命周期AnalysisServiceBootstrap:使用方法start()运行初始化代码在创buildAnalysisServiceBootstrap之后运行方法stop()right在销毁AnalysisServiceBootstrap之前(我想运行stop()停止应用程序)。

我有以下代码:

package com.pack; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.web.SpringBootServletInitializer; @SpringBootApplication public class AnalysisServiceBootstrap { // called OK on docker "start <containerId>" @PostConstruct public void start() throws Exception { // some init code } // NOT called on "docker stop <containerId>" @PreDestroy public void stop() { // some destroy code } public static void main(String[] args) { SpringApplication.run(AnalysisServiceBootstrap.class, args); } } 

出于某种原因,我无法在docker stop上运行stop()方法。 我尝试了几种方法提供在stackoverflow和其他资源,但他们都没有为我工作。

我会很高兴有代码适合你(不只是一些时尚的build议)。

这里是我的几乎精确的docker文件:

 FROM *********:6556/service-jvm ARG SERVICE_JAR_FILE ENV SERVICE_NAME service ENV HTTP_PORT 603 ENV HTTPS_PORT 604 ENV SERVICE_JAR /opt/my/project/${SERVICE_JAR_FILE} EXPOSE ${HTTP_PORT} ${HTTPS_PORT} COPY ${SERVICE_JAR_FILE} /opt/my/project/${SERVICE_JAR_FILE} CMD java -Xms1024m -Xmx1024m -dump:"/opt/my/project/dumppath" -javaagent:/opt/my/project/agent.jar -Djav.awt.headless=true -jar ${SERVICE_JAR} 

但是你被邀请在这里发布任何有效的docker文件。

非常感谢。

从文档:

docker停止

停止一个或多个正在运行的容器容器内的主进程将收到SIGTERM ,并在一个宽限期之后SIGKILL

通过执行docker stop你只需要杀死java(Spring)进程。

那么Spring的上下文将会正常closures的保证是什么呢?

在Spring应用程序中处理SIGTERM的正确方法是添加closures钩子。

最终的代码应该是这样的:

 package com.pack; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.web.SpringBootServletInitializer; @SpringBootApplication public class AnalysisServiceBootstrap { @PostConstruct public void start() throws Exception { // some init code } @PreDestroy public void tearDown() { // some destroy code } public static void main(String[] args) { Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { // write here any instructions that should be executed tearDown(); } }); SpringApplication.run(AnalysisServiceBootstrap.class, args); } } 

该过程在以下问题中进行了描述:

  • 收到SIGTERM后如何正确closuresSpring beans?
  • 如何处理SIGTERM

注册一个closures钩子到应用程序,如这里所述Spring Bootclosures钩子

每个SpringApplication都会向JVM注册一个closures钩子,以确保ApplicationContext在退出时正常closures。 所有标准的Spring生命周期callback(比如DisposableBean接口或者@PreDestroy注解)都可以使用。