菜鳥學習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能夠在部署的時候接上想要使用的日誌框架。java

從這裏能夠理解,slf4j不提供任何服務,它只是一個facade,至關於一個通用的接口。設計模式

使用slf4j須要用到api

  • 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包下的一個方法。spa

    能夠看出來,方法體裏面啥都沒有。debug

  •     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的實現。

好了下面給你們看一個我本身作的時序圖,第一次作,感受有地方沒作好,由於還不熟練,以後的博客會常常給你們畫時序圖。

 

相關文章
相關標籤/搜索