轉載自:https://www.cnblogs.com/xiaobingblog/p/11502976.html
StackOverFlow異常分析我尚未遇到過,不過做爲參考也引用過來,感謝原做者的整理。html
以上爲通用的日誌框架實現(即實現)和門面(即接口)。日誌門面的出現很大程度緩解了日誌系統的混亂,不少庫的做者不在使用具體的日誌框架實現了,而是去使用接口層,即面向接口編程。此處,貼一段話,方面更能理解。
應用程序直接使用這些具體日誌框架的API來知足日誌輸出需求固然是能夠的,可是因爲各個日誌框架之間的API一般是不兼容的,這樣作就使得應用程序喪失了更換日誌框架的靈活性。比直接使用具體日誌框架API更合理的選擇是使用日誌門面接口。日誌門面接口提供了一套獨立於具體日誌框架實現的API,應用程序經過使用這些獨立的API就可以實現與具體日誌框架的解耦,這跟JDBC是相似的。最先的日誌門面接口是commons-logging,但目前最受歡迎的是slf4j。日誌門面接口自己一般並無實際的日誌輸出能力,它底層仍是須要去調用具體的日誌框架API的,也就是實際上它須要跟具體的日誌框架結合使用。因爲具體日誌框架比較多,並且互相也大都不兼容,日誌門面接口要想實現與任意日誌框架結合可能須要對應的橋接器,就好像JDBC與各類不一樣的數據庫之間的結合須要對應的JDBC驅動同樣。數據庫
上圖來自SLF4J官網。如圖,上層都是使用SLF4JAPI對外暴露接口。SLF4JAPI使用的是slf4j-api.jar包。接着下層各個日誌框架的實現就不同了,最左邊的是slf4j的一個空實現。第二列和第五列是logback和slf4j的一個簡單實現,這2個框架沒有使用所謂的橋接器,直接繼承slf4j,實現slf4j的接口。log4j和jul的實現是要依靠橋接器,如上,slf4j-log412.jar和slf4j-jdk14.jar就是橋接器,分別鏈接slf4j,log4j和slf4j,jul。下面的log4j.jar和JVM runtime即是具體實現。編程
其餘日誌系統轉掉回slf4j,若是隻存在slf-4j轉到日誌系統實現類,便不會存在StackOverFlow的異常。若是咱們使用log4j日誌系統,但又想使用別的日誌系統,此時就要使用從日誌系統到slf4j的橋接類 log4j-over-slf4j,這個庫定義了與log4j一致的接口(包名、類名、方法簽名均一致),可是接口的實現倒是對slf4j日誌接口的包裝,即間接調用了slf4j日誌接口,實現了對日誌的轉發。api
既然存在這麼多橋接器,萬一個人系統中存在slf4j -> log4j 和 log4j -> slf4j的橋接器。。。。就會出現互相委託,無限循環,堆棧溢出的情況。全部就會有出現異常。slf4j關於橋接器的詳細介紹參考slf4j官方網站:https://www.slf4j.org/legacy.html框架
好比,我如今想使用slf4j的實現類logback日誌框架ide
1. 引入slf4j & logback日誌包和slf4j -> logback橋接器;網站
2. 排除common-logging、log4j、log4j2日誌包;日誌
3. 引入jdk-logging -> slf4j、common-logging -> slf4j、log4j -> slf4j、log4j2 -> slf4j橋接器;htm
4. 排除slf4j -> jdk-logging、slf4j -> common-logging、slf4j -> log4j、slf4j -> log4j2橋接器。blog