Apache Commons Logging的运行时发现algorithm有什么问题

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

不幸的是,关于commons-logging的最糟糕的事情,以及使得新工具不受欢迎的东西也是运行时发现algorithm。

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

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

不,这不是性能,这是类加载器的痛苦 。 JCL发现过程依靠类加载器的黑客来在运行时查找日志框架,但是这种机制导致了许多问题,包括意外的行为,很难debugging类加载问题,导致复杂性增加。 在采用commons-logging API (也提到JCL观察到的内存泄漏问题) 之前 ,Ceki(Log4J,SLF4J和Logback的作者)很好地捕获了它。

这就是为什么使用静态绑定的SLF4J被创build的原因。

Ceki是SLF4J的作者,你可能会认为他的文章有偏见,但相信我,他不是,他提供了很多参考文献(证据)来certificate他的观点。

总结一下:

  • 是的,JCL已知被打破,更好地远离它。
  • 如果你想使用一个日志外观(不是所有的项目都需要),使用SLF4J。
  • SLF4J为依然使用JCL的框架提供了一个JCL到SLF4J的桥梁,像Spring:
  • Log4J的继任者Logback是一个优秀的日志logging实现。
  • Logback本地实现了SLF4J API。 这意味着如果你使用的是Logback,你实际上使用的是SLF4J API。

也可以看看

  • Commons Logging是我的错
  • 在采用commons-logging API之前再想一想
  • SLF4J与JCL /dynamic绑定与静态绑定

Commons日志logging是一个轻量级的日志logging门面,放置在重量级日志API的顶部,是log4j ,java.util.logging或其他支持的日志API。

发现algorithm是公共日志logging用来确定在运行时使用的日志API的,因此它可以将日志调用通过其API调用到基础日志API。 这样做的好处是,如果您想创build一个logging日志的库,您不想将库的用户关联到任何特定的重量级日志logging系统。 您的代码的调用者可以通过log4j,java.util.logging等来configuration日志logging,公共日志logging将在运行时转发到该API。

Commons logging的常见抱怨:

  • 即使你不使用它,你依赖的一个库也可以,所以你必须把它包含在classpath中。
  • 针对要执行login的每个类加载器运行发现algorithm,这会产生不需要的结果,因此请确保将commons-logging.jar放在正确的类加载器中。
  • 比底层日志框架更复杂。
  • 底层日志框架的function较less。

在复杂的类path层次结构中感知更大的复杂性以及不可预测性,而没有任何可感知的好处使得公共日志logging的用户激动不已。 也鉴于这种select可能会被强迫你不使用户同情。 看到这篇文章是一个反对使用公共日志logging的引人注目的论据。

我不能说“相信不受欢迎”的一面,我只能自言自语:

Commons Logging是无论你的“真正的”日志框架可能是顶级的:Log4j,Logback或其他。

logging外观的想法是,您的应用程序获得了灵活性,以决定在运行时间哪个日志logging实施,它希望与。 外观非常聪明,可以在运行时find日志实现。

我的旧Java应用程序直接使用Log4j。 工作正常,我看不需要改变它们。 我的新Java应用程序可能会使用Logback。 我认为dynamicselect日志框架的能力是我的应用程序永远不需要的。 当然,其他人的里程可能会有所不同。


编辑:看来我错了关于共同性日志的基本原理。 @Pascal Thivent给出的链接,特别是第一个链接,更好地解释了这一点。

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

这个代码曾经被严重破坏,基本上只和JUL一起工作。

基于这方面的经验,slf4j被编写成使用静态绑定(或者习惯了,我不知道1.6版本)来select合适的框架来使用log4j,JUL或者log4j fork logback(以及更多),并且它包括一个允许现有Commons Logging代码透明地使用slf4j的桥梁。

如果可以,那么去slf4j。