java sl4j 日志_java 日志系统slf4j学习

org.slf4j.Logger

org.slf4j.LoggerFactory

slf4j的实际调用日志在运行时才会动态绑定,基本原理是查找classpath下面的jar包,如果存在slf4j的实现框架,就采用该实现框架。参考下图:

50fde18f80832c44b6c6ebd2466402b6.png

下面分析一下slf4j如何实现运行时的动态绑定日志实现框架

以下代码是org.slf4j.LoggerFactory中的部分

// We need to use the name of the StaticLoggerBinder class, we can't reference

// the class itseld.

private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";

private static void singleImplementationSanityCheck() {

try {

ClassLoader loggerFactoryClassLoader = LoggerFactory.class

.getClassLoader();

Enumeration paths;

if (loggerFactoryClassLoader == null) {

paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);

} else {

paths = loggerFactoryClassLoader

.getResources(STATIC_LOGGER_BINDER_PATH);

}

List implementationList = new ArrayList();

while (paths.hasMoreElements()) {

URL path = (URL) paths.nextElement();

implementationList.add(path);

}

if (implementationList.size() > 1) {

Util.report("Class path contains multiple SLF4J bindings.");

for (int i = 0; i < implementationList.size(); i++) {

Util.report("Found binding in [" + implementationList.get(i) + "]");

}

Util.report("See " + MULTIPLE_BINDINGS_URL + " for an explanation.");

}

} catch (IOException ioe) {

Util.report("Error getting resources from path", ioe);

}

}

我们的日志系统lib中有一个日志API:slf4j-api.jar,以及不少于一个日志框架(比如log4j,commons-logging等等)

程序运行过程中到底会使用哪个日志框架(log4j or commons-logging)呢。

这个中间需要一个API -> 实现框架的桥梁: 对接包

上面代码可以看出,通过ClassLoader来查找资源"org/slf4j/impl/StaticLoggerBinder.class",

如果有1个资源,这个就是日志实现库对接包了。如果有多个资源,则警告classpath路径下有多个slf4j的实现框架对接包。

那如果有多个实现框架对接包的情况下,到底会用哪个实现框架呢?这个就靠ClassLoader先加载到哪个了,不能确定。

因此不要在classpath下放入多个slf4j的实现框架对接包,避免出错。

上面说到关键的类StaticLoggerBinder.class,这个是判断采用哪个slf4j实现框架的关键。

StaticLoggerBinder类是slf4j组织来写的,目的是为了对接不同的日志框架。

如上图所示,slf4j-log12-xxx.jar slf4j-jdk14-xxx.jar 之类jar中就包含StaticLoggerBinder类。

实际中至少需要在classpath下提供一个实现框架,以及不多于一个对应的对接包

slf4j还有一个功能是,可以方便的迁移不同的日志框架。

比如一个项目是使用commons-logging框架来写日志的。

我们需要迁移到log4j框架来,如何处理呢。

使用slf4j将会非常方便,我们只需要做三步:

1.删除原有的commons-logging包

2.将log4j的jar加入到classpath

3.引入一个日志转换的jar,在这里是jcl-over-slf4j.jar

下面分析一下以上步骤的实现原理

commons-logging框架中的几个核心类是:

org.apache.commons.logging.Log

org.apache.commons.logging.LoggerFactory

老项目采用了commons-logging框架,必然会耦合这几个类,比如使用了如下代码:

org.apache.commons.logging.Log.error("errror msg");

要想使以上代码正常运行,而又实际是调用log4j来处理。这里就需要用到jcl-over-slf4j.jar了

jcl-over-slf4j.jar实际上是覆写了commons-logging中的几个核心类,内部采用类Adaptor,对接到了slf4j的API上面。

即jcl-over-slf4j中也有 org.apache.commons.logging.Log这个类, 他与原生的类完全不同,仅仅是适配到了slf4j-api上。

因为jcl-over-slf4j.jar是slf4j出品,slf4j把代码写到了不属于他们的package下面,感觉有点山寨,怪怪的。

这里只是举例commons-logging -> log4j, 其他的转换也类似,只是需要下载不同的适配包

整理一下日志框架迁移的流程

老日志框架:类比与上例的common-logging代码

新日志框架:类比与上例的log4j

适配包:类比与上例的jcl-over-slf4j.jar

对接包:类比与上上例的slf4j-log4j12-xxx.jar

老日志框架  ---(适配包)--->  SLF4J API ---(对接包)---> 新日志框架

fde460ec14b332f9a5ddfdfcef8c0113.png

大小: 71.9 KB

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2012-02-10 13:43

浏览 3712

评论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值