天天看點

阿裡巴巴開發手冊強制使用SLF4J作為門面擔當的秘密,被我發現了(2)

Ceki Gulcu 也覺得 JCL 不好,要不然他也不會在 2005 年自己撸一個名叫 SLF4J 的新項目,對吧?但出來混總是要付出代價的,SLF4J 隻有接口,沒有實作,總不能強逼着 Java 和 Apache 去實作 SLF4J 接口吧?這太難了,不現實。

但巨佬之是以稱之為巨佬,是因為他擁有超出普通人的驚人之處,他在 SLF4J 和 JUL、Log4j、JCL 之間搭了三座橋:

阿裡巴巴開發手冊強制使用SLF4J作為門面擔當的秘密,被我發現了(2)

巨佬動手,豐衣足食,有沒有?狠起來連自己的 Log4j 都搭個橋。

面對巨佬的霸氣,我隻想弱弱地說一句,“ SLF4J 這個門面擔當,你以為好當的啊?”

02、SLF4J 解決了什麼痛點

春秋戰國的時候,每個國家都有自己的貨币,用别國的貨币也不合适,對吧?那在發生貿易的時候就比較麻煩了,貨币不統一,就沒法直接交易,因為貨币可能不等價。

那秦始皇統一六國後,就推出了新的貨币政策,全國都用一種貨币,那之前的問題就解決掉了。

你看,同樣的道理,日志系統有 JUL、JCL,Ceki Gulcu 自己又寫了 2 種,Log4j 和 Logback,各有各的優缺點,再加上使用者千千萬,蘿蔔白菜各有所愛,這就導緻不同的應用可能會用不同的日志系統。

假設我們正在開發一套系統,打算用 SLF4J 作為門面,Log4j 作為日志系統,我們在項目中使用了 A 架構,而 A 架構的門面是 JCL,日志系統是 JUL,那就相等于要維護兩套日志系統,對吧?

阿裡巴巴開發手冊強制使用SLF4J作為門面擔當的秘密,被我發現了(2)

這就難受了!

Ceki Gulcu 想到了這個問題,并且幫我們解決了!來看 SLF4J 官網給出的解決方案。

阿裡巴巴開發手冊強制使用SLF4J作為門面擔當的秘密,被我發現了(2)

使用 jcl-over-slf4j.jar 替換 commons-logging.jar

引入 jul-to-slf4j.jar

為了模拟這個過程,我們來建一個使用 JCL 的項目。

第一步,在 pom.xml 檔案中引入 commons-logging.jar:

<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>      

第二步,建立測試類:

package com.itwanger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
 * @author 微信搜「沉默王二」,回複關鍵字 PDF
 */
public class Demo {
    private static Log logger = LogFactory.getLog(Demo.class);
    public static void main(String[] args) {
        logger.info("jcl");
    }
}      

該類會通過 LogFactory 擷取一個 Log 對象,并且使用 info() 方法列印一行日志。

調試這段代碼的過程中你會發現,Log 的實作有四種:

阿裡巴巴開發手冊強制使用SLF4J作為門面擔當的秘密,被我發現了(2)

如果沒有綁定 Log4j 的話,就會預設選擇 Jdk14Logger——它傳回的 Logger 對象,正是 java.util.logging.Logger,也就是 JUL。

是以,就可以在控制台看到以下資訊:

10月 21, 2020 3:13:30 下午 com.itwanger.Demo main

資訊: jcl

怎麼把使用 JCL 的項目改造成使用 SLF4J 的呢?

第三步,使用 jcl-over-slf4j.jar 替換 commons-logging.jar,并加入 jul-to-slf4j.jar、slf4j-log4j12.jar(會自動引入 slf4j-api.jar 和 log4j.jar):

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
    <version>1.7.25</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jul-to-slf4j</artifactId>
    <version>1.7.29</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
</dependency>