项目中有一堆日志相关的Jar包,到底应该引入哪些?排除哪些?哪些与哪些互相冲突?哪些与哪些又是相互依赖的?这类问题有时候容易让人崩溃!
本文目的就是要理清Java众多日志包的关系,明白如何进行日志转换。对于不同日志类的配置和使用方式,不在本文涉及范围之内。
日志相关Jar包分类
首先我们可以对众多的日志相关Jar包进行分类,主要分为三类:
接口类:只提供API定义,没有提供具体实现。目的是为应用层提供标准化的使用方式。既所谓的面向接口编程。
- SLF4J
- J.C.L(commons-logging)
实现类:具体的日志实现类,提供对日志的收集/管理功能。受不同需求/不同历史环境影响,各框架功能上有许多不同。但遵循进化论规律。
- Log4j
- J.U.L(jdk-logging)
- Log4j2
- Logback
桥接类:多种日志实现框架混用情况下,需要借助桥接类进行日志的转换,最后统一成一种进行输出。
- slf4j-jdk14
- slf4j-log4j12
- log4j-slf4j-impl
- logback-classic
- slf4j-jcl
- jul-to-slf4j
- log4j-over-slf4j
- icl-over-slf4j
- log4j-to-slf4j
Java日志框架发展历史
下面我们按照他们出现的先后循序和历史背景,来进行梳理。
Log4j
Apache基金会最早实现的一套日志框架,在Java1.4之前只有这一种选择。谁能想到Java1.4之前,JDK都没有内置的日志功能!。
J.U.L(jdk-logging)
终于在2002年Java1.4发布,Sun推出了自己的日志库J.U.L(jdk-logging)。但基本上是模仿Log4j的实现。有点儿鸡肋,但最起码解决了有无的问题。从此开发者有了两种选择。
J.C.L(commons-logging)
因为有了两种选择,所以导致了日志使用的混乱。所以Apache推出了J.C.L(commons-logging)。它只是定义了一套日志接口,支持运行时动态加载日志组件。应用层编写代码时,只需要使用J.C.L提供的统一接口来记录日志,在程序运行时会优先找系统是否集成Log4j,如果集成则使用Log4j做为日志实现,如果没找到则使用J.U.L做为日志实现。J.C.L的出现解决了多种日志框架共存的尴尬,也是面向接口编程思想的一种具体体现。
Slf4j
2006年,Log4j的作者Ceki Gülcü离开Apache后,又搞出来一套类似J.C.L的接口类,就是Slf4j。原因是作者觉得J.C.L这套接口设计的不好,容易让开发者写出有性能问题的代码。Slf4j做为一套标准接口,可以实现无缝与多种实现框架进行对接。它也是现在比较常用的日志集成方式。
Logback
在搞出来Slf4j之后,Ceki Gülcü又顺带开发了Logback,做为Slf4j的默认实现。在功能完整度和性能上,Logback超越了所有已有的日志实现框架。
Log4j2
2012年,Apache重写了Log4j,实现了Log4j2。在功能上面具有Logback的所有特性。算是目前功能最完善的日志框架。
通过上面的介绍,我们已经知道一共有2个日志接口标准和4个具体的实现。那一个项目中如果出现多种日志框架,我们改怎么进行统一呢?
为此,各开源组织为我们提供了一堆的日志桥接类。下面我们通过一张转换图,来了解一下各种日志框架的转换关系。
图上列举出了多种日志实现框架转换成Slf4j接口和Slf4j接口绑定多种日志实现框架所涉及到的相关Jar包。通过这些桥接包,我们可以轻松实现项目中日志框架的统一。对于哪些包需要引入/哪些包需要排除也就一目了然了。
通过这种寻根溯源的方式来学习,不仅能够弄明白每种技术出现的背景/需要应对的场景,还能够理清整体的脉络,从全局上把握技术方向。当然也能够加深对技术的理解程度。
声明:图片来源于网络,如有侵权,请联系删除。
…
欢迎关注课程:
《告别996 实现高效编程 减少开发压力》