商城首页欢迎来到中国正版软件门户

您的位置:首页 >Java 9平台日志记录器使用详解

Java 9平台日志记录器使用详解

  发布于2026-04-17 阅读(0)

扫一扫,手机访问

System.getLogger 仅适用于不引入第三方依赖且日志需求极简的场景,如模块化系统内部调试;它不是 Log4j2 或 SLF4J 的替代品,也不支持运行时输出配置,底层绑定由启动时 LoggerFinder 决定。

Java中的System.getLogger应用_Java 9引入的平台日志记录器抽象层

System.getLogger 用不用得上?

绝大多数 Java 应用——尤其是还在用 Log4j2、SLF4J + Logback 的项目——完全没必要迁移到 System.getLogger。它不是替代方案,而是 JDK 自带的轻量级门面,定位接近 java.util.logging.Logger,但更抽象、更“只读”。只有当你明确需要不引入第三方依赖、且日志需求极简(比如工具类、启动诊断、模块化系统内部调试),才值得考虑。

为什么 getLogWriter() 不生效?

System.getLogger 返回的是 Logger 实例,但它的行为完全由 JVM 启动时绑定的 System.LoggerFinder 决定。默认实现(jdk.internal.logger.DefaultLoggerFinder)根本不支持运行时替换底层输出——调用 setLogWriter 或类似方法无效,也不会报错,只是静默忽略。

  • 真正生效的方式只有:启动时通过 --add-opens java.base/jdk.internal.logger=ALL-UNNAMED + 自定义 LoggerFinder 子类,并用 -Djdk.logger.finder=your.CustomFinder 指定
  • 普通应用无法通过配置文件或 ServiceLoader 替换(JDK 9–17 中该机制未公开暴露)
  • 试图在 Spring Boot 或 Jakarta EE 环境里“接管” System.getLogger 输出,基本会失败

和 JUL(java.util.logging)的关系到底是什么?

它不是 JUL 的升级版,也不是封装层;它是并行存在的另一套抽象。JUL 的 Logger 是具体实现类,而 System.getLogger 返回的是接口 System.Logger,JDK 默认把它桥接到 JUL,但这个桥接是单向、不可配置的。

  • 调用 System.getLogger("com.example") 实际拿到的是一个包装了 JUL java.util.logging.Logger 的适配器
  • 所以 JUL 的 logging.properties 依然控制它的输出格式和级别,但 System.Logger 接口本身不暴露 setLeveladdHandler 等方法
  • 如果 JUL 被禁用(如 -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager),System.getLogger 可能退化为丢弃所有日志,且无提示

什么时候真该用?举个实际例子

模块化(JPMS)环境下的跨模块轻量调试最贴近它的设计意图。比如你写了一个 java.base 之外的平台服务模块,想记录初始化状态,又不想强制依赖 SLF4J ——这时可以用:

ModuleLayer.Controller controller = ModuleLayer.boot().controller();
controller.addModules(Set.of(YourModule.class));
// 在模块静态初始化块中
System.getLogger("YourModule").log(System.Logger.Level.DEBUG, "booted");

但要注意:System.Logger.Level 和 JUL 的 Level 枚举值不一一对应(例如没有 TRACE),且 log() 方法重载少,不支持 lazy lambda 形参(JDK 17 才加 log(Level, Supplier))。

真正容易被忽略的是:它的 isLoggable 判断开销比你想象中高——每次调用都会触发一次 LoggerFinder.getLogger 查找+适配器创建,高频日志场景下可能成为瓶颈。

本文转载于:互联网 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注