在Spring Boot应用程序中关闭浏览器选项卡时结束JVM

时间:2018-12-11 09:16:21

标签: java spring-boot

我有一个spring-boot web应用程序,将以jar文件的形式分发。启动应用程序的代码如下:

private static ConfigurableApplicationContext ctx;

    public static void main(String[] args){

        if(ctx == null) {
            ctx = SpringApplication.run(MyApplication.class, args);
        }       
        try {
            openHomePage("http://localhost:8090/");
        }catch(Exception e) {
            logger.error("Error occured starting the application: ", e);
            ctx.close();
        }

    }


private static void openHomePage(String url) throws IOException, URISyntaxException {
        if(Desktop.isDesktopSupported()) {
            URI homePage = new URI(url);
            Desktop.getDesktop().browse(homePage);
        }else {
            Runtime runtime = Runtime.getRuntime();
            runtime.exec(new String[]{"cmd", "/c","start chrome " + url});
        }       

    }

这将在Chrome中打开主页,无论是从Eclipse运行它还是双击jar文件。

问题是,当我从jar文件启动应用程序并关闭浏览器选项卡时,该应用程序继续在JVM中运行,而我不得不手动从task manager终止它这很烦人。如果我没有杀死JVM并再次双击jar文件,则该应用程序不会像第一次那样自动启动,因此我必须手动打开一个新的浏览器选项卡并键入{{ 3}},以便使用该应用程序。

在用户关闭浏览器选项卡之后是否有可能杀死每个进程,以便当他们下次需要使用该应用程序时单击jar文件时,会自动打开一个新的浏览器选项卡?

先谢谢了。

2 个答案:

答案 0 :(得分:2)

解决方案

这可能不是最佳解决方案,但可以有效治疗。

*第1步-从浏览器发送心跳

var heartBeatIntervals = null;

$( document ).ready(function() {

//this ajax call will be fired every 2 seconds as long as the browser tab stays open.
// the time intervals can of course be modified
heartBeatIntervals = setInterval(() => {
        $.ajax({
            type:'POST',
            url: 'http://localhost:8090/MyController/checkHeartbeats'
        })
    }, 2*1000);

});

*第2步-处理服务器中的心跳信号

@Controller
@RequestMapping("/MyController")
public class MyController {

    //declare an instance variable to store the number of missed heartbeats
    private int missedHeartbeats = 0;

    //reset the counter to 0 upon receiving the heartbeats
    @PostMapping("/checkHeartbeats")
    public void checkHeartbeats() {
        missedHeartbeats = 0;
    }

    //increase the missedHeartbeats by one every 3 seconds - or whatever
    @Scheduled(fixedRate = 3000)
    public void schedule() {
        missedHeartbeats++;
        //check how many heartbeats are missed and if it reaches to a certain value
        if(missedHeartbeats > 5) {
            //terminate the JVM (also terminates the servlet context in Eclipse)
            System.exit(0);
        }
    }

}

*步骤-3启用计划

为了在spring-boot应用程序中使用任何调度,您需要在@EnableScheduling方法所在的类中添加main注释。

就是这样。

答案 1 :(得分:0)

Eclipse中有一个停止按钮。并且在无法使用的情况下:
您可以将javascript中的内容连续发送到服务器,并且当服务器1秒钟未收到该消息时,这表示该网页已关闭,请自行停止。

解决方案1 ​​

  1. 在任何@Controller中使用一种方法来处理心跳请求。
  2. 将最新的心跳时间存储在任何类别的static字段中,初始值可以是0或-1,指示尚未打开网页。
  3. 使用@Scheduled任务来检索上一个心跳时间并将其与当前时间进行比较。每2秒安排一次任务。 https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/scheduling.html#scheduling-annotation-support
  4. 根据需要停止JVM,可能是System.exit(0)

解决方案2

如果您可以在网页上添加关闭按钮,将会更容易。被单击时,它指示服务器停止,然后关闭网页本身。 https://stackoverflow.com/a/18776480/9399618