Spring的@PreDestroy导致随机记录而不记录

2024-05-11

我正在使用 Spring,并且在终止时我让 @PreDestroy 清理 bean。我不明白为什么日志记录有时会成功,而有时会失败。

// Using Log4j2
Logger log = LogManager.getLogger(MyClass.class);

@PreDestroy
public void close() {
    log.warn("Test");
}

有时我什么也得不到(没有记录“测试”),其他时候我会得到:

[13:48:44] INFO  MyClass: Test

如果我包括System.out.println("Is this run?");在 close() 方法中,它总是会打印。

我实际上不确定发生了什么。我不知道是否是因为 JVM 正在关闭并且记录器被杀死......但我认为这会引发某种异常?

请注意,日志记录都记录到文件+标准输出,我不知道这是否会影响任何内容。日志记录对于其他无数行代码都可以正常工作,但对于这行代码却不行。

注意:如果最终成为这个特定的库,我愿意切换日志库。

编辑:MyClass 将是 spring.xml 文档中的一个 bean。


我认为归根结底是这样的,从Runtime.addShutdownHook https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#addShutdownHook-java.lang.Thread-:

当虚拟机开始其关闭序列时,它将启动所有已注册的关闭挂钩一些未指定的订单并让它们同时运行。

因此,只要 LogManager 和 Spring IOC 容器都被 JVM 关闭钩子关闭,就无法确保消息会被记录下来。如果LogManager先关闭,消息就会丢失。如果首先关闭 IOC 容器,则会记录该消息。

如果您在 JEE 容器中运行,您可能几乎无法改变这一点。

但是,如果您在独立环境中运行,则可以添加shutdownHook="disable"到 Log4j 2<configuration>标签。这会阻止 Log4j 2 注册它自己的关闭挂钩。然后,而不是调用ctx.registerShutdownHook()(关闭 IOC 的推荐方法),您注册自己的关闭挂钩。就像是:

class MyShutdownHook extends Thread {
    private AbstractApplicationContext ctx;
    public MyShutdownHook(AbstractApplicationContext ctx) {
        this.ctx = ctx;
    }
    public void run() {
        ctx.close();
        Set<LoggerContext> contexts = new HashSet<>();
        for (Logger logger : LoggerContext.getLoggers()) {
            contexts.add(logger.getContext());
        }
        for (LoggerContext ctx : contexts) {
            Configurator.shutdown(LogManager.getContext());
        }
    }
}

AbstractApplicationContext ctx = /* create context */
Runtime.getRunTime().addShutdownHook(new MyShutdownHook(ctx);

更新:更正了关闭 Log4j2 的过程。
警告:我远离我常用的构建机器,所以我没有编译这个,但我相信它使用了正确的 API。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring的@PreDestroy导致随机记录而不记录 的相关文章

随机推荐

  • FTP 入站通道适配器的 FTP 问题

    我们的项目使用 ftp inbound channel adapter 从 FTP 服务器轮询文件 它工作正常 但在轮询之间不起作用 当我看到 FTP 服务器日志时 我看到 425 无法打开数据连接 现在 当我重新启动或停止并再次启动 ft
  • VSCode 在 React 的 JSX 中错误地格式化三进制

    我正在运行 VSCode 来开发我的 React 应用程序 我有一个简单的三元 isLoading
  • 在 python 中查找价格动量的有效方法:对列的最后 n 个条目求平均值

    我正在定义价格动量是给定股票过去动量的平均值n days 反过来 动量是一种分类 如果当天的收盘价高于前一天 则每天标记为 1 如果当天的收盘价低于前一天 则标记为 1 我的库存变化百分比如下 df close in percent np
  • modinfo srcversion:如何从我的源生成此版本?

    我有一个 Linux 模块的编译版本 然后我有大约 20 多个其源代码的变体 由于各种愚蠢的错误 我已经不知道哪个版本的源代码是我用来制作模块的实际版本了 我注意到modinfo
  • 如何调试内部错误?

    所以我有课Foo最终应该调整并重新加载类 它也有一个方法 private void redefineClass String classname byte bytecode ClassFileLocator cfl ClassFileLoc
  • C#中析构函数的使用?

    我对 C 中析构函数的使用有点困惑 据我所知我们不能打电话 根据我的愿望 析构函数会在垃圾收集器之前自动调用 以对类 对象 执行一些工作 所以我想问一下我们是否在 C 中使用析构函数 那么我们何时需要垃圾收集器 据我所知 析构函数可以处理内
  • 如何粘贴到Excel B列的最后一行?

    我需要将单元格从 H2 L2 一直向下剪切并将其粘贴到 B 列的最后一行 数据每次都会不同 所以我无法对任何范围进行硬编码 VBA 代码会很好 从 H2 L2 向下剪切并粘贴 插入到 B 列的最后一行 到目前为止我得到了 Range H2
  • 这个错误从何而来?错误:com.facebook.FacebookException:无法获取应用程序名称

    我无法弄清楚这一点 我已将我的密钥哈希和所有内容添加到 Facebook 网页 但我无法找出此错误 11 12 19 51 27 744 D HelloFacebook 5188 Error com facebook FacebookExc
  • DART:将来 then 的语法

    我不明白的语法then clause 1 myFuture 6 then erg gt print erg What s erg gt expr语法上 我以为这会是一个函数 但是 then callHandler2 erg 不起作用 错误
  • 如何使用 jQuery Validate 正确验证放置在多个选项卡上的 Twitter Bootstrap 表单?

    我有一个表单位于多个 Twitter 的 Bootstrap 选项卡上
  • 带有 viewbags 的 MVC 数据集

    如何将数据集放入视图袋中并在视图中显示结果 我有一个来自模型的数据集 并将其写入视图包 我想使用 foreach 循环从视图中的视图包中获取数据行 我已经有一个变量进入视图 所以我无法正常传递数据集 每页我还会有许多其他数据集 所以我认为
  • Android 操作系统上的 NFC 堆栈

    有人可以帮助我了解 NFC Android 堆栈的当前状态吗 随着OS 2 3发布了小型 NFC 支持 仅限于 NXP 标签读取 后来 Google 增强了 API 所以在OS 2 3 3支持更广泛的标签 并且还可以使用 p2p 我的问题是
  • 如何在 Angular 模板中嵌入 GitHub gist?

    角度忽略script其模板中包含标签 但加载 GitHub gist 需要它们 执行此操作的最佳做 法是什么 使用iframe 创造script动态标记 或者是其他东西 一种方法是创建一个iframe with script里面并在你希望你
  • 这是复制类的好方法吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我是一个十足的菜鸟 所以如果我不适合问这个问题 请告诉我 如果需要的话请给我引导 无论如何 我一直在学习值类型和引用类型 并且想知道定义一个像这
  • 文件中缺少所需的架构 i386

    添加 MapKit 和 CoreLocation 框架后 我在构建应用程序时遇到问题 它们都是 4 3 框架 并且该应用程序过去可以与 UIKit CoreGraphics 和 Foundation 一起正常工作 只是这两个框架给我带来了问
  • InstallShield XML 文件更改 - 安装时更改节点属性

    我正在使用 InstallShield 2012 构建 Web 服务安装 并且需要根据用户输入修改应用程序的 Web config 文件 我在 DestinationFolder 对话框之后引入了 PromptServerAndDataba
  • Javascript:更改浏览器后退按钮的功能

    有没有办法让用户的浏览器上的后退按钮调用 JavaScript 函数而不是返回页面 您无法覆盖这样的行为 如果用户通过链接访问您的页面 则单击 后退 将使他们再次离开该页面 但是 您可以使页面上的 JavaScript 操作将条目添加到历史
  • javax.el.PropertyNotFoundException:在 java.lang.String 类型上找不到属性“tname”

    我之前使用的是 scriptlet 但现在我改用了 mvc 我无法检索 JSP 页面上的值并收到错误 javax el PropertyNotFoundException Property tname not found on type j
  • 如何在 Swift 中将 Int 转换为字符

    我在这里挣扎了十多分钟 失败了 我屈服了 我需要在 Swift 中将 Int 转换为 Character 但无法解决它 Question 你如何转换 cast an Int integer to a Character char 在斯威夫特
  • Spring的@PreDestroy导致随机记录而不记录

    我正在使用 Spring 并且在终止时我让 PreDestroy 清理 bean 我不明白为什么日志记录有时会成功 而有时会失败 Using Log4j2 Logger log LogManager getLogger MyClass cl