2012-01-03 20 views
1
登录任何类

假设一个shutdownHook为:如何允许从shutdownHook

class ShutdownHolder extends Thread { 

    public void run() { 
     Logger logger = LoggerFactory.getCoreLogger(ShutdownHolder.class); 
     try { 
     logger.info("Shutdown hook is running..."); 
     doSomething(); 
     logger.info("Shutdown hook end."); 
     } catch(Exception e) { 
     logger.severe("Unexpected ERROR during shutdown", e); 
     } 
    } 
    } 

如何避免记录ShutdownHook结束之前不会被关闭?

例如,doSomething()方法可以在其他可访问的类上调用几个方法,也可以写入日志。我不想跳过所有这些日志。

+0

你是什么意思?为什么记录仪会关闭? 'doSomething()'应该返回到'run()'方法,不是吗? – adarshr 2012-01-03 16:26:27

+0

http://docs.oracle.com/cd/E17409_01/javase/6/docs/api/java/lang/Runtime.html#addShutdownHook%28java.lang.Thread%29“他们也不应该盲目地依赖服务可能已经注册了自己的关机挂钩,因此可能自己正在关机。“记录器似乎有它自己的shutdownHook。 – Mik378 2012-01-03 16:33:41

回答

1

所以,除了一些反省黑客之外,我不觉得一个简单的方法来做到这一点不幸。在1.6 JDK下,关机挂钩存储在IdentityHashmap中,该订单不提供有保证的订单。实际上,关闭挂钩是以随机顺序调用的,这取决于该地图的内部。

在反思方面,我试着做下面的事情,但hookMap对我来说是空的。如果你能得到它的工作,那么你可能会删除log4j钩子,并在钩子或其他东西结束时手动调用它。

Class<?> clazz = Class.forName("java.lang.ApplicationShutdownHooks"); 
Field field = clazz.getDeclaredField("hooks"); 
field.setAccessible(true); 
@SuppressWarnings("unchecked") 
Map<Thread, Thread> hookMap = (Map<Thread, Thread>) field.get(null); 

然而,我会强烈建议做一些其他比关闭挂钩。如何在main完成之前调用自己的挂钩?对我们来说,我们大量使用Spring和DisposableBean模式。那些豆从实例化类的时候开始按相反顺序调用,所以依赖于记录器的任何事物在关闭时仍然具有记录器。

希望这会有所帮助。