slf4j介紹以及與Log4j、Log4j2、LogBack整合方法


翻了一下百度和官網。這么介紹slf4j。

  slf4j 全稱 Simple Logging Facade for Java,是日志框架的一種抽象,那么也就是說 slf4j 是不能單獨使用的必須要有其他實現日志框架來配合使用,並且如果要啟用slf4j框架要導入slf4j-api-xxx.jar 這個包, 這個包是slf4j 實現各種支持的日志框架的包比如log4j、log4j2、logback等。  slf4j也已經支持這幾種日志組件。

  這里拿slf4j 和logback的整合使用為例,先來看依賴關系

  簡單的從淺層源碼來查找依賴關系

  通常我們在java類中使用日志要先拿到Logger,如:

  private static final Logger          LOGGER        = LoggerFactory.getLogger(Test.class);

  我們來看getLogger方法的代碼,注意 getLogger 這個靜態方法是屬於 slf4j-api-xxx.jar的org.slf4j包下的。

public static Logger getLogger(Class<?> clazz) { Logger logger = getLogger(clazz.getName()); if (DETECT_LOGGER_NAME_MISMATCH) { Class<?> autoComputedCallingClass = Util.getCallingClass(); if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) { Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", logger.getName(), autoComputedCallingClass.getName())); Util.report("See " + LOGGER_NAME_MISMATCH_URL + " for an explanation"); } } return logger; }

 繼續看方法第一行 getLogger的代碼

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

繼續看getILoggerFactory方法

public static ILoggerFactory getILoggerFactory() { if (INITIALIZATION_STATE == UNINITIALIZED) { synchronized (LoggerFactory.class) { if (INITIALIZATION_STATE == UNINITIALIZED) { INITIALIZATION_STATE = ONGOING_INITIALIZATION; performInitialization(); } } } switch (INITIALIZATION_STATE) { case SUCCESSFUL_INITIALIZATION: return StaticLoggerBinder.getSingleton().getLoggerFactory(); case NOP_FALLBACK_INITIALIZATION: return NOP_FALLBACK_FACTORY; case FAILED_INITIALIZATION: throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG); case ONGOING_INITIALIZATION: // support re-entrant behavior. // See also http://jira.qos.ch/browse/SLF4J-97
            return SUBST_FACTORY; } throw new IllegalStateException("Unreachable code"); }

注意看:StaticLoggerBinder.getSingleton().getLoggerFactory();    其中StaticLoggerBinder 類是 logback-classic-xxx.jar 包下的 並且實現了 slfj-api-xxx.jar包的 LoggerFactoryBinder接口。 也就是說在 slf4j-api-xxx.jar包下的 getILoggerFactory 方法中調用了logback-classic-xxx.jar 包的StaticLoggerBinder類中的方法並且 該類實現了slf4j-api-xxx.jar 中的 LoggerFactoryBinder接口。 

public ILoggerFactory getLoggerFactory() { if (!initialized) { return defaultLoggerContext; } if (contextSelectorBinder.getContextSelector() == null) { throw new IllegalStateException("contextSelector cannot be null. See also " + NULL_CS_URL); } return contextSelectorBinder.getContextSelector().getLoggerContext(); }

而在getLoggerContext()方法中  StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext)  這段代碼傳入的參數是LoggerContext 是logback-class-xxx.jar 包中的。 並且StatusPrinter類是 logback-core-xxx.jar包中的。

這樣就形成了繼承關系為:  logback-core-xxx.jar  -->  logback-classic-xxx.jar --> slf4j-api-xxx.jar --> 自己的代碼。

可能有疑問是slf4j怎樣知道與誰整合拿誰的LoggerFactory , 其實是通過不同的jar包來實現的。

  slf4j與log4j整合導入的jar包為

    1. slf4j-api.jar
    2. slf4j-log4j12.jar
    3. log4j.jar

  slf4j與log4j2整合導入的jar包為:

    1. slf4j-api.jar
    2. log4j-slf4j-impl.jar
    3. log4j-api.jar
    4. log4j-core.jar

  slf4j與logback整合導入的jar包為:

    1. slf4j-api.jar
    2. logback-core.jar
    3. logback-classic.jar

  所以這樣當更換日志框架的時候 slf4j接口是不用動的,只需要換下對應的實現框架的包就可以了。並且代碼不用更改。

 

本文純屬原創, 轉載請注明出處!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM