菜鸟学习slf4j框架

什么是slf4j框架?

The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired logging framework at deployment time.

这个是官方的介绍,意思就是slf4j是一个简单的java日志框架facade,facade是门面的意思,相当于一个服务的接口,具体的日志功能由具体的日志(如java的util包中的logging、logback、log4j)框架提供,使用slf4j可以在部署的时候接上想要使用的日志框架。

从这里可以理解,slf4j不提供任何服务,它只是一个facade,相当于一个通用的接口。

使用slf4j需要用到

  • slf4j-api-1.x.xx.jar

从包名可以看出来这个包是和api有关的,仅仅是api肯定是无法工作的。如果我们想要使用slf4j需要依赖另外的jar包,而这些依赖的jar包称为"SLF4J bindings"。官方原文解释SLF4J bindings:

The SLF4J distribution ships with several jar files referred to as "SLF4J bindings", with each binding corresponding to a supported framework.

按照官方介绍的SLF4J bindings有如下几个:

  • slf4j-log4j12-1.7.21.jar

    slf4j-log4j用于整合log4j,使用非常广泛,使用时需要在依赖里加上log4j的jar包。

  • slf4j-jdk14-1.7.21.jar

    slf4j-jdk用于整合java.util.logging。只要是jdk1.4以上就OK。

  • slf4j-nop-1.7.21.jar

    slf4j-nop提供了一个没有任何实现代码的实现。什么意思呢,我截图slf4j包下的一个方法。

    181957_jdRi_2360147.png可以看出来,方法体里面啥都没有。

  •     slf4j-simple-1.7.21.jar

    slf4j-simple提供了简单的实现,除了info或者更高级别的日志会print外,全部都打印到System.err上。

  • slf4j-jcl-1.7.21.jar

    slf4j-jcl整合jcl,jcl没听过。。。先无视。

  • logback-classic-1.0.13.jar

    没听过logback。。。无视

从这里可以知道想要使用slf4j不仅仅是slf4j-api这个包就行了,还需要具体的日志框架。比如我之前做过的项目都用log4j,所以我必须有slf4j-log4j这个包和原本的log4j包。

 

如何使用slf4j?

我猜大部分人在深入了解一个框架前就会用这个框架了。因为如果都没用过根本不会去深入了解。

用slf4j很简单,下面是我在项目里的用法

public class xxx {
    ...
    ...
    public static final Logger logger = LoggerFactory.getLogger(xxx.class);
    ...
    ...
    public void login(){
        ...
        logger.info("ID为{},名为{}的用户登录了服务器!",xx,xx);
        ...    
    }
}

在类里面定义一个静态的Logger属性,属性由LoggerFactory的getLogger方法初始化。getLogger方法接收一个class对象,作用是输出时把类名作为日志的前缀。

这里我在用户登录服务器的时候通过logger对象的info方法来输出了一段日志。

需要注意的是slf4j到1.7版本之后才支持可变参数。

如info方法:void info(String var1, Object... var2);

在此之前多参数都是通过数组实现的:void info(String var1, Object[] var2);

 

从源码分析slf4j

从使用过程来看,slf4j的核心类很明显是Logger类,但是看了源码会发现Logger类只是一个接口。这个不难理解,因为slf4j只是一个 Facade。

浏览一遍Logger接口,会发现里面的方法有规律,根据规律可以把接口的方法分成5大类

  • trace
  • debug
  • info
  • warn
  • error

从方法名可以看出来这些方法是日志的5个级别,也就是Logger类是一个提供输出不同级别日志的接口。

Logger类的初始化方式是通过LoggerFactory来创建的。从名字一看就知道这里采用了工厂设计模式。Logger可以是不同的实现,但是创建过程我们不过关心,交给工厂来操作就OK了。

通过LoggerFactory的getLogger(Class<?> clazz)方法可以创建一个Logger      LoggerFactory.getLogger(xxx.class);

方法内部其实是调用了另外一个重载的方法Logger logger = getLogger(clazz.getName());

也就是使用了类的全限定名来作为参数。

getLogger(String name)方法又调用了getILoggerFactory()方法,这个方法的作用是获得一个Logger工厂。getILoggerFactory方法很关键,它调用了SLF4J bindings的StaticLoggerBinder类。比如我的项目里用了Log4j,这里StaticLoggerBinder会返回一个Log4jLoggerFactory对象。

得到了Log4jLoggerFactory就可以得到Log4j的Logger了吗?也没那么快。因为Log4jLoggerFactory是slf4j-log4j包的类。也就是说,还没有真正调用Log4j。slf4j-log4j相当于只是一个中间件,来协调Log4j和Slf4j。

我们来看看Log4jLoggerFactory的getLogger方法,方法里面调用了LogManager的getLogger方法。LogManager才是log4j的类。从名字可以看出来LogManager是用来管理Logger的类。暂时称它为log管理器吧,log管理器里面也有一个getLogger方法,这里才是真正创建Log4j的Logger的地方。调用了log管理器的getLogger后,Log4jLoggerFactory的getLogger方法就得到了一个Log4j的Logger。

Log4jLoggerFactory得到了Log4j的Logger对象之后会把Logger返回给Slf4j-api嘛?我们看源码,并不是这样。这里使用了一个适配器Log4jLoggerAdapter。看Log4jLoggerAdapter的源码会发现它也实现了Logger接口,所以Log4jLoggerFactory可以直接把适配器返回给Slf4j-api。

Log4jLoggerAdapter是干嘛的呢,适配器嘛,就是为了适应某一个东西,比如这里是为了适配Log4j。也就是说吧Log4j封装,在调用Logger接口的时候能够使用Log4j的实现。

好了下面给大家看一个我自己做的时序图,第一次做,感觉有地方没做好,因为还不熟练,之后的博客会经常给大家画时序图。

 

230348_MC6a_2360147.png

 

转载于:https://my.oschina.net/aidonggua/blog/719233

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值