Spring Boot 和 Logback 中不同 Classloader 加载的类

我遇到了一个我想理解的奇怪问题。如果有人有一个解决方案,那就太好了,但我实际上正在寻找理解为什么会发生这种情况:


我编写了一个自定义 Logback 布局。我正在扩展ch.qos.logback.contrib.json.classic.JsonLayout和覆盖addCustomDataToJsonMap。如果在日志记录事件参数列表中找到某种类型的参数,我想添加其他属性:


  protected void addCustomDataToJsonMap(Map<String, Object> map, ILoggingEvent event) {


    if (event.getArgumentArray() == null) {

      return;

    }


    for (Object argument : event.getArgumentArray()) {


      System.out.println(argument.getClass().getClassLoader()); // 1

      System.out.println(JsonAttribute.class.getClassLoader()); // 2


但是参数列表 (1) 中的对象的类和静态引用的对象的类 (2) 由不同的类加载器加载,如输出所示:


org.springframework.boot.devtools.restart.classloader.RestartClassLoader@618157b2

sun.misc.Launcher$AppClassLoader@18b4aac2

因此,我无法将对象转换为所需的类型并访问其方法。我想到的解决方法是通过Reflecion 访问这些值,但我宁愿使用实际值。


我想这只是我的开发环境的问题,但正如第一部分所述,我真的很想了解发生了什么。


编辑:


正如预期的那样:当在没有 spring 开发工具的情况下以“生产”模式运行应用程序时,所有类都由同一个类加载器加载。


牧羊人nacy
浏览 84回答 1
1回答

九州编程

我假设您正在使用 Spring DevTools。他们创建一个单独的类加载器以更快地重新启动应用程序。该类加载器应该加载您的类,并在重新启动时被丢弃,而不是重新启动整个应用程序。您应该能够将其配置为排除自定义 Logback 布局,以便在应用程序重新启动时不会重新加载它(链接文档中的第 20.2.6 节)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java