system.exit和finally

由于工程需要,需要起一个CT任务。在CT任务的时候,起的是一个main方法。在结束的时候调用了System.exit(0)。但是发现调用System.exit的时候,无论是finally还是Spring的@PreDestroy注解的方法都没有执行。所以去查了相应的资料。

How does Java's System.exit() work with try/catch/finally blocks
可见System.exit是直接调用了关闭Jvm的方法,自然不会调用Spring的BeanFactory的关闭方法。
我们通过源码可以更加直观的观察到其运行方法:

public static void exit(int status) {
    Runtime.getRuntime().exit(status);
}

从方法的注释中可以看出此方法是结束当前正在运行的Java虚拟机,这个status表示退出的状态码,非零表示异常终止。注意:不管status为何值程序都会退出,和return 相比有不同的是:return是回到上一层,而System.exit(status)是回到最上层。
由以上分析可知,在使用System.exit的时候并不会调用finally中的方法,更别提Spring的注解@PreDestroy。
如果希望上面的情况能够正常工作,需要如下的进行:
获取ApplicationContext。在AbstractApplicationContext中有一个方法方法close()可以调用。所以可以如下进行:

public static void shutDown() {
        LOGGER.info("start to shut down application context");
        if (null != ac) {
            if (ac instanceof AbstractApplicationContext) {
                AbstractApplicationContext beanFactory = (AbstractApplicationContext) ac;
                beanFactory.close();
            }
        }
    }

同时将System.exit(0)删除即可。
如同上面讲的,除了采用调用AbstractApplicationContext的close()方法外,还也可以使用

((AbstractApplicationContext)appCtx).registerShutdownHook();

讨论参考how-to-close-a-spring-applicationcontext
来将applicationContext注册到jvm关闭的钩子上,这样在jvm关闭的时候就会自动调用AbstractApplicationContext的doClose方法。
这部分的内容可以参考源码来进一步了解:

@Override
    public void registerShutdownHook() {
        if (this.shutdownHook == null) {
            // No shutdown hook registered yet.
            this.shutdownHook = new Thread() {
                @Override
                public void run() {
                    synchronized (startupShutdownMonitor) {
                        doClose();
                    }
                }
            };
            Runtime.getRuntime().addShutdownHook(this.shutdownHook);
        }
    }

最本质的内容就是调用了Runtime.getRuntime().addShutdownHook(Thread hook);

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,026评论 19 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,974评论 6 342
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,785评论 18 399
  • 人最大的幸运,不是捡钱,也不是中奖,而是有人可以鼓励你、指引你、帮助你。其实,限制人们发展的,往往不是智商和学历,...
    幸福的眼泪_52da阅读 209评论 0 1
  • 知道这本书,还是参加剽悍行动营的第一天分享课上,安叔讲了这本书,当时他说的最打动我的一句话就是:当你处于人生...
    镶金边的乌云阅读 241评论 0 0