作者: Jitwxs
鏈接: https://jitwxs.cn/e2390047.html
一、前言
在進行 Java 開發時,通常我們會選擇 Slf4j 作為日志門面,但日志實作卻不盡相同,如果系統運行中同時存在多個日志實作,就會出現類似下圖的 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 依賴,則重復執行排除的操作,
<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>
近期熱文推薦:
1.1,000+ 道 Java面試題及答案整理(2021最新版)
2.別在再滿屏的 if/ else 了,試試策略模式,真香!!
3.臥槽!Java 中的 xx ≠ null 是什么新語法?
4.Spring Boot 2.5 重磅發布,黑暗模式太炸了!
5.《Java開發手冊(嵩山版)》最新發布,速速下載!
覺得不錯,別忘了隨手點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/310342.html
標籤:Java
