Java 如何允许从shutdownHook登录任何类

Java 如何允许从shutdownHook登录任何类,java,logging,process,design-patterns,Java,Logging,Process,Design Patterns,假设一个关闭钩为: class ShutdownHolder extends Thread { public void run() { Logger logger = LoggerFactory.getCoreLogger(ShutdownHolder.class); try { logger.info("Shutdown hook is running..."); doSomething(); logg

假设一个关闭钩为:

 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);
      }
    }
  }
如何避免记录器在关闭钩子结束前未关闭


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

因此,除了一些反射黑客之外,不幸的是,我没有找到一种简单的方法来实现这一点。在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);
Class clazz=Class.forName(“java.lang.ApplicationShutdownHooks”);
字段字段=clazz.getDeclaredField(“挂钩”);
字段。setAccessible(true);
@抑制警告(“未选中”)
Map hookMap=(Map)field.get(null);
但是,我强烈建议您不要使用关机挂钩。在
main
完成之前调用自己的钩子怎么样?对于我们来说,我们大量使用Spring和
DisposableBean
模式。这些bean的调用顺序与类实例化时相反,因此依赖于记录器的任何东西在关闭时仍然拥有记录器


希望这能有所帮助。

因此,除了一些反射黑客之外,不幸的是,我看不到一个简单的方法来做到这一点。在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);
Class clazz=Class.forName(“java.lang.ApplicationShutdownHooks”);
字段字段=clazz.getDeclaredField(“挂钩”);
字段。setAccessible(true);
@抑制警告(“未选中”)
Map hookMap=(Map)field.get(null);
但是,我强烈建议您不要使用关机挂钩。在
main
完成之前调用自己的钩子怎么样?对于我们来说,我们大量使用Spring和
DisposableBean
模式。这些bean的调用顺序与类实例化时相反,因此依赖于记录器的任何东西在关闭时仍然拥有记录器


希望这有帮助。

你是什么意思?为什么要关闭记录器
doSomething()
应该返回到
run()
方法,不是吗?“他们也不应该盲目地依赖那些可能已经注册了他们自己的关机钩子的服务,因此他们自己可能正在关机。”Logger似乎有自己的关机钩子。你是什么意思?为什么要关闭记录器
doSomething()
应该返回到
run()
方法,不是吗?“他们也不应该盲目地依赖那些可能已经注册了他们自己的关闭钩子的服务,因此他们自己可能正在关闭。”记录器似乎有自己的关闭钩子。