【问题标题】:Catch application stop event for Spring-boot application捕获 Spring-boot 应用程序的应用程序停止事件
【发布时间】:2016-06-16 07:57:01
【问题描述】:

是否有一种干净的方法来检测 spring-boot 应用程序何时停止并在之前执行一些操作?用于停止服务的 CommandLineRunner 类型

提前致谢

【问题讨论】:

标签: spring spring-boot


【解决方案1】:

我想出了这个解决方案。如果你有更好的,欢迎分享

@Component
public class PortalServiceLifeCycle implements CommandLineRunner {

static final Logger LOGGER = LoggerFactory.getLogger(PortalServiceLifeCycle.class);

@Override
public void run(String... arg0) throws Exception {
    LOGGER.info("###START FROM THE LIFECYCLE###");
}

@PreDestroy
public void onExit() {
    LOGGER.info("###STOP FROM THE LIFECYCLE###");
}
}

【讨论】:

    【解决方案2】:

    不知道你有没有完美解决这个问题。我最近遇到了这个问题,并得到了一个有点不同的解决方案。

    首先,我的 Spring Boot 应用程序是一个 Tomcat 嵌入式应用程序。 (这个问题的第二种方法不依赖于web结构,朋友别生气。)这种情况下,自然就产生了通过注册监听器来捕获停止事件的想法。我就是这样做的,

    @WebListener
    public class HelloListener implements ServletContextListener {
    
        @Override
        public void contextInitialized(ServletContextEvent servletContextEvent) {
            System.out.println("HelloListener contextInitialized");
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent servletContextEvent) {
            System.out.println("HelloListener contextDestroyed");
        }
    }
    

    同时,在您的 Application 类上添加注解 @ServletComponentScan。

    当然,还有其他方法可以注册一个ServletContextListener,一旦注册了,就可以在contextDestroyed函数中获取停止事件。

    但是,这与我的问题不太相符。我必须在 Spring Bean 被销毁之前捕获停止事件。第二个解决方案来了。

    修改您的应用程序主方法,如下所示:

        SpringApplication application = new SpringApplication(DemoApplication.class);
        application.addListeners(new MyListener());
        application.run(args);
    

    并提供类 MyListener 的定义:

    class MyListener implements ApplicationListener<ContextClosedEvent>{
    
        @Override
        public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
            // your code here
        }
    }
    

    注意:第二种解决方案与 Tomcat 或其他 Web 容器无关。 Spring文档中没有介绍ContextClosedEvent,但我在源码中找到了,我认为它非常有用。

    如果这能帮助到某人,我将非常高兴。

    【讨论】:

    • 从您的帖子中,我得到了这样做的想法@Component public class ApplicationEventListener implements ApplicationListener&lt;ApplicationEvent&gt; { @Override public void onApplicationEvent(ApplicationEvent applicationEvent) { if(applicationEvent instanceof ContextClosedEvent){ // do stuff }
    【解决方案3】:

    这取决于您想要做什么,但您可以做的一件事是拥有一个实现 SmartLifecycle 并实现 stop 方法的 bean。每当上下文停止时,您都会收到回调。请注意,这并不一定意味着该进程正在关闭。如果你想在发生这种情况时调用一些代码,我会注册一个关闭钩子,正如 Sven 在评论中所写的那样。

    【讨论】:

      【解决方案4】:

      类似于ApplicationReadyEvent,你可以使用ContextClosedEvent

      @Component
      public class ContextClosedEventListener {
      
          @EventListener(ContextClosedEvent.class)
          public void onContextClosedEvent(ContextClosedEvent contextClosedEvent) {
              System.out.println("ContextClosedEvent occurred at millis: " + contextClosedEvent.getTimestamp());
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2018-11-10
        • 1970-01-01
        • 1970-01-01
        • 2018-07-03
        • 1970-01-01
        • 2021-10-19
        • 2017-04-14
        • 2012-05-18
        • 1970-01-01
        相关资源
        最近更新 更多