Slf4j 包沖突問題原因與解決

一、前言

在進行 Java 開發(fā)時,通常我們會選擇 Slf4j 作為日志門面坏瞄,但日志實現卻不盡相同。如果系統(tǒng)運行中同時存在多個日志實現甩卓,就會出現類似下圖的 Warning鸠匀。

二、問題原因

我們知道 SpringBoot 默認使用的日志實現是 Logback逾柿,因此我們嘗試在項目中引入 Log4j 的依賴時缀棍,就復現了上圖的報錯。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

上圖報錯告知我們存在多個 SLF4J bingdings鹿寻,分別位于 logback 和 log4j 包中睦柴,有兩個 StaticLoggerBinder。

我們知道使用 Slf4j 毡熏,需要 LoggerFactory.getLogger() 方法獲取實例坦敌。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

private final Logger logs = LoggerFactory.getLogger(xxx.class);

我們就可以通過這個作為入口,去看看源碼的實現痢法。如下圖所示狱窘,我標注了需要關注的核心代碼。

  • (1)調用 getILoggerFactory() 方法得到 LoggerFactory财搁。
  • (2)對于首次調用蘸炸,INITIALIZATION_STATE 應該是 UNINITIALIZED,所以進入初始化的邏輯尖奔,調用方法 performInitialization()搭儒。
  • (3)調用 bind() 方法穷当。
  • (4)如果不是 isAndroid(),調用 findPossibleStaticLoggerBinderPathSet() 方法淹禾,故名思意馁菜,查找可能的 staticLoggerBinder,注意這里返回的類型是 SET铃岔,即可能是多個汪疮。
  • (5)在findPossibleStaticLoggerBinderPathSet() 這個方法內,首先通過 classLoader 加載了 org/slf4j/impl/StaticLoggerBinder.class 這個類的 path毁习,它可能存在多個智嚷,因此使用了 while 獲取了所有的 path,并最終返回纺且。
  • (6)reportActualBinding() 方法會校驗 SET 的 size盏道,如果大于 1,就會打印出一開始我們看見的 Warning 了隆檀。

三摇天、問題解決

解決思路就是將你不想要的日志實現從依賴包中排除掉即可,通過 IDEA 提供的 Diagrams 能夠非常方便的查看項目中的依賴關系恐仑。

打開項目的 POM 文件泉坐,右鍵選擇 Diagrams -> Show Dependencies

假設我們想要排除 logback 依賴,使用 log4j裳仆。Ctrl + F 搜索 logback腕让,可以找到引用該依賴的樹形結構。

點擊窗口左上角的下圖中的這個圖標歧斟,可以只看當前選中的這個依賴的關系纯丸。

選中后效果如下:

如上圖所示,logback 由 spring-boot-starter-logging 引入静袖,最頂層是由 spring-boot-starter-web 和 spring-boot-starter-test 引入觉鼻。

我們嘗試在 spring-boot-starter-web 中排除該依賴,應該就可以了队橙。如果排出后重新搜索仍然存在 logback 依賴坠陈,則重復執(zhí)行排除的操作。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>` 

四捐康、總結

日志框架沖突特別對于新手來說處理起來比較頭疼仇矾,因為涉及到了日志接口和日志實現。

我們推崇的應該是面向接口編程解总,因此我們大到開源項目贮匕,小到公司的公共 jar 包,應當合理利用 Maven 的傳遞機制花枫。具體的日志實現不應該傳遞出去刻盐,避免影響到調用的下游方掏膏。

<optional>true</optional>` 
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市隙疚,隨后出現的幾起案子壤追,更是在濱河造成了極大的恐慌,老刑警劉巖供屉,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異溺蕉,居然都是意外死亡伶丐,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進店門疯特,熙熙樓的掌柜王于貴愁眉苦臉地迎上來哗魂,“玉大人,你說我怎么就攤上這事漓雅÷急穑” “怎么了?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵邻吞,是天一觀的道長组题。 經常有香客問我,道長抱冷,這世上最難降的妖魔是什么崔列? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮赵讯,結果婚禮上,老公的妹妹穿的比我還像新娘边翼。我一直安慰自己,他們只是感情好组底,可當我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著西傀,像睡著了一般斤寇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上娘锁,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天饺鹃,我揣著相機與錄音莫秆,去河邊找鬼间雀。 笑死,一個胖子當著我的面吹牛镊屎,可吹牛的內容都是我干的惹挟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼连锯,長吁一口氣:“原來是場噩夢啊……” “哼用狱!你這毒婦竟也來了运怖?” 一聲冷哼從身側響起夏伊,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎咏连,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體鲁森,經...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡刀森,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了研底。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡冠蒋,死狀恐怖,靈堂內的尸體忽然破棺而出抖剿,到底是詐尸還是另有隱情,我是刑警寧澤斩郎,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布喻频,位于F島的核電站缩宜,受9級特大地震影響,放射性物質發(fā)生泄漏锻煌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一匣沼、第九天 我趴在偏房一處隱蔽的房頂上張望捂龄。 院中可真熱鬧释涛,春花似錦倦沧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽愈污。三九已至,卻和暖如春轮傍,著一層夾襖步出監(jiān)牢的瞬間暂雹,已是汗流浹背创夜。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留驰吓,地道東北人。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓姑廉,卻偏偏與公主長得像翁涤,于是被迫代替她去往敵國和親桥言。 傳聞我的和親對象是個殘疾皇子葵礼,可洞房花燭夜當晚...
    茶點故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內容