Apache Commons Logging的运行时发现算法存在什么问题?

47

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

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

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

4个回答

83

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

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

这就是为什么创建了使用静态绑定的SLF4J。

你可能认为作为SLF4J的作者,Ceki的文章有偏见,但相信我,他没有,他提供了大量引用来证明他的观点。

总之:

  • 是的,众所周知,JCL是破损的,最好远离它。
  • 如果您想使用日志门面(不是所有项目都需要),请使用SLF4J。
  • SLF4J为仍在使用JCL的框架提供了JCL到SLF4J桥接,如Spring :(
  • 我认为Logback是Log4J的继承者,是一个更好的日志实现。
  • Logback本地实现了SLF4J API。这意味着如果您使用Logback,则实际上正在使用SLF4J API。

另请参阅


14

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

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

对于commons logging的常见抱怨:

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

复杂的类路径层次结构似乎更加复杂和不可预测,而没有任何实际好处,这使得使用commons-logging的用户感到不安。此外,如果这个选择被强制施加给你,也不会让用户感到同情。请参阅本文以获得反对使用commons-logging的有力论据。


2

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

Commons Logging是一个门面,位于您的“真实”日志框架之上:Log4j、Logback或其他。

日志门面的想法是,您的应用程序在运行时获得决定要使用哪个日志实现的灵活性。这些门面足够聪明,可以在运行时找到日志实现。

我的旧Java应用程序直接使用Log4j。工作得很好,我看不到需要更改它们的必要性。我的新Java应用程序可能会使用Logback。我认为动态选择日志框架的能力是我的所有应用程序都永远不需要的东西。当然,别人的经验可能有所不同。


编辑:看起来我对Commons Logging的原理理解是错误的。@Pascal Thivent给出的链接,特别是第一个链接,解释得更好。


1

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

那段代码以前严重有问题,基本上只能与 JUL 一起使用。

基于这些经验,编写了 slf4j,它使用静态绑定(或曾经使用,我不确定版本 1.6)来选择要使用的适当框架,包括 log4j、JUL 或 log4j 分支 logback(等等),并且它包括一个桥接器,允许现有的 Commons Logging 代码透明地使用 slf4j。

如果可以的话,请选择 slf4j。


2
你为什么认为SLF4J版本1.6中的静态绑定方法发生了变化? - Ceki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接