46

Dave Syer (SpringSource)在他的博客中写道:

不幸的是,commons-logging 最糟糕的地方,也是它在新工具中不受欢迎的地方,也是运行时发现算法。

为什么?它的运行时发现算法有什么问题?表现?

4

4 回答 4

81

为什么?它的运行时发现算法有什么问题?表现?

不,这不是性能,而是类加载器的痛苦。JCL 发现过程依赖于类加载器黑客来在运行时找到日志框架,但这种机制会导致许多问题,包括意外行为、难以调试导致复杂性增加的类加载问题。在采用 commons-logging API 之前,Ceki(Log4J、SLF4J 和 Logback 的作者)在 Think 中很好地捕捉到了这一点(其中还提到了使用 JCL 观察到的内存泄漏问题)。

这就是创建使用静态绑定的 SLF4J 的原因。

Ceki 作为 SLF4J 的作者,您可能会认为他的文章有偏见,但相信我,事实并非如此,他提供了大量参考资料(证据)来证明他的观点。

总结一下:

  • 是的,JCL 是出了名的坏,最好远离它。
  • 如果您想使用日志外观(并非所有项目都需要),请使用 SLF4J。
  • SLF4J 为仍在使用 JCL(如 Spring)的框架提供了 JCL 到 SLF4J 的桥梁:(
  • 我发现 Log4J 的继任者 Logback 是一个优秀的日志实现。
  • Logback 原生实现了 SLF4J API。这意味着如果你使用 Logback,你实际上是在使用 SLF4J API。

也可以看看

于 2010-07-11T16:05:59.153 回答
14

Commons logging 是一个轻量级的日志外观,它位于重量级日志 API 之上,例如log4j、java.util.logging 或其他支持的日志 API。

发现算法是公共日志记录用来确定您在运行时使用的日志记录 API 的算法,因此它可以通过其 API 将日志调用定向到底层日志记录 API 。这样做的好处是,如果您想创建一个执行日志记录的库,您不希望将您的库的用户绑定到任何特定的重量级日志记录系统。您的代码的调用者可以通过 log4j、java.util.logging 等配置日志记录,并且公共日志记录将在运行时转发到该 API。

公共日志记录的常见问题:

  • 即使您不使用它,您所依赖的库也可能因此您必须将它包含在您的类路径中。
  • 为您要登录的每个类加载器运行发现算法,这可能会产生不需要的结果,因此请确保将 commons-logging.jar 放入正确的类加载器中。
  • 比底层日志框架更复杂。
  • 底层日志框架的功能更少。

在没有任何感知好处的情况下,复杂的类路径层次结构中感知到的更大的复杂性和不可预测性使公共日志记录的用户感到不安。考虑到这种选择可能是强加给你的,这不会让用户产生同情。 有关反对使用公共日志记录的令人信服的论点,请参阅这篇文章

于 2010-07-11T11:48:27.740 回答
2

我不能谈论“被认为不受欢迎”的方面,我只能为自己说话:

Commons Logging 是您的“真实”日志框架之上的一个外观:Log4j、Logback 或其他任何东西。

日志外观的想法是,您的应用程序可以灵活地在运行时决定要使用哪个日志实现。外观足够聪明,可以在运行时找到日志实现。

我的旧 Java 应用程序直接使用 Log4j。工作正常,我认为没有必要更改它们。我较新的 Java 应用程序可能会使用 Logback。我认为动态选择日志框架的能力是我的任何应用程序都不需要的。当然,其他人的里程可能会有所不同。


编辑:看起来我对 Commons Logging 的基本原理是错误的。@Pascal Thivent 给出的链接,尤其是第一个链接,更好地解释了这一点。

于 2010-07-11T11:46:50.977 回答
1

Commons Logging 包含在运行时确定是使用 log4j 还是 java.util.logging.* 的逻辑。

该代码曾经被严重破坏,基本上只与 JUL 一起使用。

基于这方面的经验,编写了 slf4j,它使用静态绑定(或者习惯于,我不确定 1.6 版)来选择合适的框架来使用 log4j、JUL 或 log4j fork logback(等等),它包括允许现有 Commons Logging 代码透明地使用 slf4j 的桥梁。

如果可以,请选择 slf4j。

于 2010-07-11T13:16:15.993 回答