程序中一直在用log4j,之前都沒了解過,只知道是打印日志信息的。最近獨立新建了幾個開發工程,發現slf4j老有沖突,開始關注起來,我用log4j打印日志,與slf4j有毛關系,怎么老沖突呢。網上找了下原因,解決了下問題,才發現slf4j的重要性。參考多篇博文,特此記錄。
slf4j:Simple Logging Facade for Java,為java提供的簡單日志Facade。Facade:門面,更底層一點說就是接口。他允許用戶以自己的喜好,在工程中通過slf4j接入不同的日志系統。更直觀一點,slf4j是個數據線,一端嵌入程序,另一端鏈接日志系統,從而實現將程序中的信息導入到日志系統並記錄。
因此,slf4j入口就是眾多接口的集合,他不負責具體的日志實現,只在編譯時負責尋找合適的日志系統進行綁定。具體有哪些接口,全部都定義在slf4j-api中。查看slf4j-api源碼就可以發現,里面除了public final class LoggerFactory類之外,都是接口定義。因此,slf4j-api本質就是一個接口定義。
不同的日志庫如java.util.logging、Apache log4j、logback,SLF4J不同於其他日志類庫,與其它有很大的不同。SLF4J(Simple logging Facade for Java)不是一個真正的日志實現,而是一個抽象層( abstraction layer),它允許你在后台使用任意一個日志類庫。如果是在編寫供內外部都可以使用的API或者通用類庫,那么你真不會希望使用你類庫的客戶端必須使用你選擇的日志類庫。
下圖比較清晰的描述了他們之間的關系:
當系統采用log4j作為日志框架實現的調用關系:
首先系統包含slf4j-api作為日志接入的接口;
at compile時slf4j-api中public final class LoggerFactor類中
private final static void bind() 方法會尋找具體的日志實現類綁定,主要通過
StaticLoggerBinder.getSingleton();語句調用
slf4j-log4j12:鏈接slf4j-api和log4j中間的適配器。它實現了slf4j-apiz中StaticLoggerBinder接口,從而使得在編譯時綁定的是slf4j-log4j12的getSingleton()方法
log4j:這個是具體的日志系統。通過slf4j-log4j12初始化Log4j,達到最終日志的輸出。
另附兩個引入log4j后遇到的問題解決方法:
1.無論怎么修改log4j日志級別為debug,都不能正常打印sql,
2.啟動報錯
Caused by: java.lang.IllegalStateException: org.slf4j.LoggerFactory could not be successfully initialized. See also http://www.slf4j.org/codes.html#unsuccessfulInit
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:310)
3.SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".該錯誤是警告,程序可以運行。
是由於log4j-* 、slf4j-log4j12-*、slf4j-api-*三者缺少其中一個,或者三者版本不匹配。
例如我工程中三個版本分別是log4j-1.2.14.jar、slf4j-api-1.6.2.jar、slf4j-log4j12-1.6.2。
另外,在網上下載相關jar包時發現csdn中資源下載jar有的要積分,這類公共jar也要積分,有點坑吧。有個方法是把相關jar版本寫到pom.xml中,讓它去下載好了在拷貝過來。
個人理解這三個包的關系:slf4j-api提供日志接口,slf4j-log4j12提供接口到log4j實現的適配,log4j是具體實現。日志實現類庫有java.util.logging、Apache log4j、logback。看了那么多博文,思路中就整理出來這么句話,應該不沒理解錯吧。*_*.
相關博文地址:
http://www.importnew.com/7450.html
http://blog.csdn.net/tengdazhang770960436/article/details/18006127