引言
最近一直在看spring源码,于是想写几篇关于spring源码的博客,但是spring源码的调用链太深了,而且也过于复杂,我认为不适合写博客来记录。
于是苦思冥想,还是写一篇Java日志方面的文章吧,相比于spring源码,看起来也显得简单又轻松,愉快又享受!
正文
我们先来说说Java具体有哪些日志吧:
Log4j
Apache Log4j是一个基于Java的日志记录工具。它是由Ceki Gülcü首创的,现在则是Apache软件基金会的一个项目。 log4j是几种Java日志框架之一。
<!-- log4j 1.0版本maven依赖 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
- log4j的使用
Logger logger = Logger.getLogger("log4j");
logger.info("hello world!");
Log4j 2.0
log4j团队创建了log4j的继任者,版本号为2.0的新版本。log4j 2.0着重于log4j 1.2、1.3、java.util.logging和logback中的问题,并解决这些框架中的架构问题。此外,log4j 2.0提供了一个插件架构,这使得其更可扩展。log4j 2.0不是与1.x向后兼容的版本,虽然有一个“适配器”可用。
<!-- log4j 2.0之后的版本maven依赖 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.12.1</version>
</dependency>
- log4j 2.0的使用
Logger logger = Logger.getLogger("log4j 2.0");
logger.info("hello world!");
JUL(Java Util Logging)
这是Java官方团队自己提供的一个Java日志工具,来自于:java.util.logging 包
- Jul的使用
Logger logger = Logger.getLogger("jul");
logger.info("hello world!");
logback
首先logback和log4j都是 Ceki Gülcü 一个人写的,我愿称他为Java日志框架的王!
Logback旨在作为流行的log4j项目的后继者,从log4j离开的地方接手。
Logback的体系结构足够通用,可以应用在不同的情况下。 目前,logback分为三个模块:logback-core,logback-classic和logback-access。
logback-core模块为其他两个模块奠定了基础。 logback-classic模块可以与log4j的显着改进版本同化。 此外,经典的logback本质上实现了SLF4J API,因此您可以轻松地在logback和其他日志框架(例如log4j或java.util.logging(JUL))之间来回切换。
<!-- logback 的maven依赖 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>
- logback使用
Logger logger = LoggerFactory.getLogger("chapters.introduction.HelloWorld1");
logger.debug("Hello world.");
小结
以上的java日志的实现方法都是只要将Java的依赖导入项目就可以进行使用了。所以我将上面所有总结的日志工具分为一类。
而下面所介绍的两个日志工具本身自己没有进行日志打印的功能,他需要导入上面的日志工具才可以进行打印。
我们向下进行:
JCL(Jakarta Commons Logging)
JCL全称:Jakarta Commons Logging,是由Apache软件基金会在log4j的基础上开发的。
它与其它的日志工具有所不同,使用他时必须依赖其它的日志包才能进行打印,类似于设计模式中的工厂模式,如图我们可以看到,当使用log4j的时候是直接可以打印日志,JCL并不进行打印,而是做了一个代理功能,只要你引入log4j的包就会使用log4j进行打印,没有log4j包就会使JUL进行打印日志。
为什么要这样做呢?
其实这里是根据工厂模式的设计思想而生的。举个例子:
一位老员工写了一个管理系统,也可以正常上线使用了,突然有一天这位老员工进了 ICU ,没办法,只好让你来接手了,并要求将之前所使用的 log4j 日志框架换成 JUL 。因为代码不同,你不仅要换jar包,还要将代码中所使用到log4j的地方全都换成JUL。无奈的你,头发一天天的在减少。
突然有一天你了解到了JCL日志框架,只要使用JCL日志框架后只要换个jar包就可以换成你想要的日志框架了,瞬间你看到了希望,这几天掉的头发又长回来了!离ICU又远了一步!
<!-- JCL 的maven依赖 -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
- JCL的使用:
Log log = LogFactory.getLog("jcl");
log.info("hello");
好神奇!我们已经知道JCL可以进行日志框架转换的了,但是这是怎么实现的呢?
接下来,我们来看看源码中是怎么实现的:
首先在 LogFactory 的实现类的 LogFactoryImpl 中的 discoverLogImplementation()方法 中有个以 classesToDiscover 数组的长度进行for循环,如图:
我们接着看看 classesToDiscover 数组到底是什么,如图所示:是一个容纳长度为4 的字符串,这四个字符串分别指向了 log4j, Jdk14Logger, Jdk13LumberjackLogger,SimpleLog 四个日志工具。接着点进 createLogFromClass() 函数看看做了什么事情。
由于这个函数过长,我们就将重要的截图下来看到,其实它是根据循环得到的字符串,通过反射实例化了日志对象,从零开始循环,没有通过反射得到该对象时,说明没有引入这个包,所以返回null。
这时我们就明白了,当我们项目中引入了 log4j ,则会实例化使用该日志;如果没有引入log4j的包,JCL将会依次使用下面JDK自带的日志框架进行使用。
SLF4J(The Simple Logging Facade for Java )
上官网:SLF4J官网
没错!!SLF4J的创造者又是他 Ceki Gülcü ,Java日志的王名不虚传!!
SLF4J 可作为各种日志记录框架(例如java.util.logging,logback,log4j)的简单外观或抽象,允许最终用户在部署时插入所需的日志记录框架。
1,绑定器
没错,非常抽象的一段解释,其实 SLF4J 和 JCL 有着类似的功能,但是 SLF4J 更为强大。那我们就来了解一下他的强大之处吧,上图!
这是官网上的一张图,本想自己画的,但是再怎么画也超越不了作者的理解呀!(好吧,我承认是我懒了。。。)不管怎么说,这张图还是非常清晰的。让我来解释一下,从左边第一张说明当你只导入 slf4j-api.jar 时,并不能使用任何日志功能。如果你想使用logback日志框架必须还要导入logback-classic.jar 和 logback-core.jar;当使用log4j时,就要导入slf4j-log412.jar包。这一功能官网上称为 Binding(绑定器)。
这个功能与JCL类似,但是 SLF4J 更为灵活,想换什么日志框架都可以,而JCL只能按照给定的顺序进行更换。
2,桥接器
话不都说,上图(没错,还是官网上的图!)
什么是桥接:举个例子来说明吧:
你在为公司写项目,你使用的日志框架是 SLF4J 绑定器 logback 绑定器,这是根据业务需要你要导入一个web框架进行使用,而这时发现这个web框架所使用的日志工具是log4j,而架构师要你统一日志工具。这时就可以使用 SLF4J 的桥接了:
SLF4J装载了一个叫 log4j-over-slf4j的模块。它允许log4j用户转移已存在的应用到SLF4J,同时不用改变一行代码,只需要简单地用 log4j-over-slf4j.jar 代替 log4j.jar。
那它是怎么工作的呢?
log4j-over-slf4j 模块包含了大部分使用的log4j类的替代类,是org.apache.log4j.Category, org.apache.log4j.Logger, org.apache.log4j.Priority,org.apache.log4j.Level, org.apache.log4j.MDC, and org.apache.log4j.BasicConfigurator.这些被替代类重新把所有的工作指向相关的SLF4J类。
在你自己的应用中使用 log4j-over-slf4j ,第一部是定位,然后用 log4j-over-slf4j.jar 代替 log4j.jar 。注意你仍需要SLF4J绑定,它是 log4j-over-slf4j.jar 完全工作的根基。
在大部分情况下,为了从log4j迁移到SLF4J,所有的花费只是替换jar文件。
注意由于这个迁移,log4j配置文件将不再被获得。如果你需要迁移log4j.properties文件到logback,log4j 转换器会给帮助。配置logback,请参考它的手册 。
总结
这就是关于Java日志工具的介绍了,有什么问题或者文章哪里有出入的地方可以指出了,我们一起讨论。祝愿大家都能成为Java滴神!