【问题标题】:Standard way to implement a Logger across classes in Java?在 Java 中跨类实现 Logger 的标准方法?
【发布时间】:2026-02-07 18:40:01
【问题描述】:

我正在构建一个包含许多类的 Javafx 应用程序。 我想使用所有类的 java 日志记录。但是所有选项似乎都带有过多或重复的代码。这些是我能想到的:

  1. 将 Logger 声明为每个类中的私有静态最终字段,即

    private static final Logger LOGGER = Logger.getLogger(MyClass.class.getName());

这个选项似乎有点烦人,必须在每个班级都这样做。

  1. 将 Logger 从主类传递给每个构造函数

又显得不优雅

  1. 仅为记录器创建一个类,然后为每个日志项调用该类的静态方法。 似乎只为记录器创建一个额外的类是多余的。

那么你们是如何处理这种情况的呢?只是选择最不坏的选项吗?

【问题讨论】:

  • 我使用 4. 为 Service、Dao 等声明基本泛型类。我声明protected final Logger log = LoggerFactory.createLogger(this.getClass());,然后根据类的层从这些类扩展。
  • 那么你如何在你的程序类中包含这个记录器而不是任何东西的子类?
  • 好吧,我用上面的那行声明了一个通用的记录器,但是这些应该是最小的类,比如实用程序。
  • 如果我理解正确,比如 javafx,你会声明 LoggingApplication extends Application 之类的东西,它会包含记录器。但是你如何让这个记录器进入你所有的程序类呢?我的大多数程序类都没有扩展任何主要的 java 类。
  • 这是关于设计的。我发现这是一个很好的设计,可以满足我的需求。如果您不这样做,那么您可以找到更适合您需求的另一个。对此没有确切的答案。

标签: java logging


【解决方案1】:

我不同意第三个选项的“过度”:“包装器”选项实际上非常优雅,因为它有一个专用的记录器类(SRP),它允许您切换实现(log4j,@ 987654323@,java.util.logging 等)“在幕后”,而不将其余代码耦合到该实现。

正如 Luiggi 在下面的 cmets 中提到的 SLF4J 就是这样的实现。

【讨论】:

  • SLF4J 这第三个选项。 SLF4J 是对其他日志库的包装记录器库。
【解决方案2】:

选项 1 与选项 3 相结合(就像人们提到的使用 slf4j 之类的包装器),这将允许在实现之间切换被广泛使用。

declare Logger as a private static final field in each class i.e.

private static final Logger LOGGER = Logger.getLogger(MyClass.class.getName());

声明一个记录器并不是什么大问题,您应该能够在您的 IDE 中定义一个新的类模板,它会自动生成记录器代码。

【讨论】: