当前位置: 首页 > 知识库问答 >
问题:

Spring Boot关闭endpoint应该关闭整个JVM进程,还是仅仅关闭应用程序上下文?

訾晋
2023-03-14

共有1个答案

艾焱
2023-03-14

感谢Stéphane,我找到了阻止JVM进程在到达/shutdownendpoint后终止的原因。在我的一个依赖项中有一个ScheduledExecutor没有随应用程序上下文关闭,它阻止JVM进程关闭(即使在应用程序上下文关闭之后)。我写了一个简单的例子来展示如何再现该行为,还有一个例子展示如何解析它。

当您命中/关闭endpoint时,此示例不会终止JVM进程:

@SpringBootApplication
public class AppSpringConfiguration {

    public static void main(String[] args) {
        SpringApplication.run(AppSpringConfiguration.class);
    }

    @Bean
    public ClassWithExecutor ce() {
        return new ClassWithExecutor();
    }

    @PostConstruct
    public void startScheduledTask() {
        ce().startScheduledTask();
    }

    @RestController
    public static class BusinessLogicController {

        @RequestMapping(value = "/hi")
        public String businessLogic() {
            return "hi";
        }
    }            

    public static class ClassWithExecutor {
        ScheduledExecutorService es;

        ClassWithExecutor() {
            this.es = Executors.newSingleThreadScheduledExecutor();
        }

        public void startScheduledTask() {
            es.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    System.out.println("Printing this every minute");
                }
            }, 0, 3, TimeUnit.SECONDS);
        }    
    }
}

通过添加在应用程序上下文关闭时关闭ScheduledExecutor的shutdown钩子,JVM进程现在在到达/shutdownendpoint后被终止:

@SpringBootApplication
public class AppSpringConfiguration {

    public static void main(String[] args) {
        SpringApplication.run(AppSpringConfiguration.class);
    }

    @Bean
    public ClassWithExecutor ce() {
        return new ClassWithExecutor();
    }

    @Bean
    ShutdownAction sa() {
        return new ShutdownAction(ce());
    }

    @PostConstruct
    public void startScheduledTask() {
        ce().startScheduledTask();
    }

    @RestController
    public static class BusinessLogicController {

        @RequestMapping(value = "/hi")
        public String businessLogic() {
            return "hi";
        }
    }

    public static class ShutdownAction implements ApplicationListener<ContextClosedEvent> {
        private ClassWithExecutor classWithExecutor;

        ShutdownAction(ClassWithExecutor classWithExecutor) {
            this.classWithExecutor = classWithExecutor;
        }

        @Override
        public void onApplicationEvent(ContextClosedEvent event) {
            classWithExecutor.shutdown();
        }
    }

    public static class ClassWithExecutor {
        ScheduledExecutorService es;

        ClassWithExecutor() {
            this.es = Executors.newSingleThreadScheduledExecutor();
        }

        public void startScheduledTask() {
            es.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    System.out.println("Printing this every minute");
                }
            }, 0, 3, TimeUnit.SECONDS);
        }

        public void shutdown() {
            es.shutdownNow();
        }
    }
}
 类似资料:
  • 嗨,我必须为Android和iPhone开发一个应用程序。我知道为Android和iPhone开发的语言,但如果我只想为所有平台创建一个应用程序,我该如何使用?我必须创建一个简单的应用程序,其中包含一些来自服务器的新闻,这个应用程序可以从iTunes和PlayStore下载,但它是同一个应用程序。我知道有电话差距,但我不知道是否可以做到我想要的。我想用另一种方式使用jQuery Mobile,但当

  • 我有一个主(屏幕)gui窗口,需要打开几个“多输入”窗口(jdialog或当不可能使用jframe时),例如添加首选项(4个文本字段,带有2个文件选择器和2个单选按钮)。在这些JDialogs(或JFrames)中按OK/Cancel时,我的整个应用程序将关闭。我不想那样。我该怎么防止呢? 第一次尝试:我尝试了intelliJ选项“新- 第二次尝试:我“手工”编写了一个类,创建了一个JDialog

  • 对于JavaFX,通常是: 是否有方法检测TornadoFX视图关闭?

  • 启动 1. 轻触主画面上您想启动的应用程序图标。 显示LiveArea™。 2. 轻触[开始]。 中断/继续 按下PS键即可返回LiveArea™。若要继续,请轻触[继续]。 关闭 1. 按下PS键。 返回LiveArea™。 2. 请由画面右上角将LiveArea™撕下。

  • 问题内容: 在Swing中,您可以简单地用于在关闭窗口时关闭整个应用程序。 但是,在JavaFX中找不到等效项。我有多个打开的窗口,如果一个窗口关闭,我想关闭整个应用程序。用JavaFX做到这一点的方法是什么? 编辑: 我了解可以覆盖以在窗口关闭时执行一些操作。问题是应该执行什么操作才能终止整个应用程序? 类中定义的方法不执行任何操作。 问题答案: 当最后一个关闭时,应用程序自动停止。目前,您的类

  • 我做了一个jsf应用程序。这个应用程序有一个包含开始、停止按钮的菜单。当按下开始时,应用程序开始从网站获取数据,并更新其数据库。应用程序还有更新过程的进度条。但是,这个过程需要很长时间才能完成。我希望当我关闭浏览器时,它应该继续更新数据库。此外,当我再次打开它时,我应该得到以前的状态。然而,这并没有发生。当我关闭浏览器时,应用程序也关闭了。我该怎么办? 谢谢。