【Slf4j分析】slf4j-api和slf4j-simple

一.基礎

使用maven:


<dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
       <version>1.7.21</version>
</dependency>

<dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-simple</artifactId>
       <version>1.7.21</version>
</dependency>

slf4j-api包 是日誌的接口,log4j,logback等等纔是日誌的真正實現。
slf4j-simple包 是slf4j提供的一個簡單實現 。
當我們調用接口時,接口的工廠會自動尋找恰當的實現,返回一個實現的實例給我提供服務,如下圖。

這裏寫圖片描述

二.重要的類和接口

最關鍵的2個接口,分別是Logger和ILoggerFactory。最關鍵的類,是LoggerFactory

Logger接口

用來記錄日誌,提供了打印各種級別日誌的功能。
實現類有NOPLogger 和 SimpleLogger等,NOPLogger如同它的名字一樣:什麼都不做 ,SimpleLogger在slf4j-simple包中,可通過配置日誌輸出方式,顯示格式,日誌級別等來打印日誌。

ILoggerFactory接口

通過他來直接獲取Logger

LoggerFactory 類

這個類是獲取Logger的門面,他的內部是通過ILoggerFactory來獲取Logger的

三.LoggerFactory 類詳解

LoggerFactory使用getLogger()方法獲取Logger對象

public class Main {
    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(Main.class);

        logger.debug("debug");
        logger.info("info");
    }
}

getLogger()是重載方法,可以接受一個字符串或class類型,接受字符串參數的方法如下所示:

 public static Logger getLogger(String name) {
     ILoggerFactory iLoggerFactory = getILoggerFactory();//***
     return iLoggerFactory.getLogger(name);
 }

進入getILoggerFactory()方法,這個類簡化如下:

 public static ILoggerFactory getILoggerFactory() {
     //使用加鎖的方式保證僅僅一次初始化(具體看源碼)
     performInitialization();

     //使用StaticLoggerBinder類獲取真正的日誌工廠,將在下一節介紹   
     return StaticLoggerBinder.getSingleton().getLoggerFactory();

 }

performInitialization()詳解,這個方法包括bind()–綁定 和versionSanityCheck() 版本檢查,把他們合併簡化如下

private final static void performInitialization() {
        bind();//綁定日誌實現

        versionSanityCheck();//版本檢查

}

bind()方法簡化如下

 private final static void bind() {

      Set<URL> staticLoggerBinderPathSet = null;

      staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
      //處理多個日誌框架的問題
      reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);

      //獲取日誌綁定類LoggerFactoryBinder
      StaticLoggerBinder.getSingleton();
      INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
      reportActualBinding(staticLoggerBinderPathSet);
      fixSubstituteLoggers();
      replayEvents();
      // release all resources in SUBST_FACTORY
      SUBST_FACTORY.clear();

}

四.LoggerFactoryBinder接口及其StaticLoggerBinder類

LoggerFactoryBinder接口是slf4j中的,日誌框架必須有一個StaticLoggerBinder類實現這個接口
slf4j通過StaticLoggerBinder來幫頂具體的日誌框架,它有兩個重要方法

  • getSingleton()來獲取StaticLoggerBinder的一個單例,
  • getLoggerFactory()方法來獲取真正的日誌工廠(ILoggerFactory的具體子類)

五.Logger

用來記錄日誌

實現類SimpleLogger

這個類是simpl-logger中的類,他提供了記錄日誌等多種功能

六.ILoggerFactory

這個接口有一個方法,用來獲取日誌

public interface ILoggerFactory {

    public Logger getLogger(String name);
}

slf4j-simple中的實現類SimpleLoggerFactory

public class SimpleLoggerFactory implements ILoggerFactory {

    ConcurrentMap<String, Logger> loggerMap;

    //初始化 1.持有的ConcurrentHashMap用來保存所有日誌
    //2.
    public SimpleLoggerFactory() {

        loggerMap = new ConcurrentHashMap<String, Logger>();
        SimpleLogger.init();
    }

    /**
     * Return an appropriate {@link SimpleLogger} instance by name.
     */
    public Logger getLogger(String name) {
        Logger simpleLogger = loggerMap.get(name);
        if (simpleLogger != null) {
            return simpleLogger;
        } else {
            Logger newInstance = new SimpleLogger(name);
            Logger oldInstance = loggerMap.putIfAbsent(name, newInstance);
            return oldInstance == null ? newInstance : oldInstance;
        }
    }

    /**
     * Clear the internal logger cache.
     *
     * This method is intended to be called by classes (in the same package) for
     * testing purposes. This method is internal. It can be modified, renamed or
     * removed at any time without notice.
     *
     * You are strongly discouraged from calling this method in production code.
     */
    void reset() {
        loggerMap.clear();
    }
}

七.總結

- slf4j-api中的 slf4j-simple中的實現 說明
1 LoggerFactory類 - 通過ILoggerFactory子類獲取Logger對象
2 ILoggerFactory接口 SimpleLoggerFactory類 直接獲取Logger對象
3 Logger接口 SimpleLogger類 記錄日誌
4 LoggerFactoryBinder接口 StaticLoggerBinder 綁定具體的日誌(ILoggerFactory類)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章