天天看點

Spring5新特性之日志體系

日志系統對于各大主流架構或是自己的應用中都是不可或缺的重要組成部分,最近比較關注spring,是以就來分析下spring的日志系統以及spring4和spring5的日志有哪些差別。

對于各種日志技術,可參見我的另一篇文章:https://blog.csdn.net/baomw/article/details/84526738

1,我們先從spring4和5的核心包context包的依賴關系,來看看其涉及的日志依賴包

Spring5新特性之日志體系

<spring4依賴關系圖>

Spring5新特性之日志體系

<spring5依賴關系圖>

從上面的依賴關系不難看出,我們spring4所依賴的jar就是我們的jcl,而spring5則依賴了一個叫spring-jcl的包,至于這個spring-jcl到底是什麼,是不是就是我們的jcl呢,我們可以通過例子來看看,這個到底是不是我們jcl的實作。

2,我們知道,jcl列印日志有log4j時通過log4j輸出日志,沒有則通過jul輸出日志。

Spring5新特性之日志體系
Spring5新特性之日志體系

通過上圖,可以知道,當加了log4j的時候,通過log4j來輸出日志,沒加則通過jul來輸出日志,可見spring4引入的jcl就是我們原生的jcl(原理參見我的另一篇文章,上有連接配接。)

Spring5新特性之日志體系

可以看到,spring5就算我加了log4j的jar,依然還是通過jul來列印的日志,說明spring-jcl至少不是我們所知道的jcl,那麼spring-jcl到底是什麼呢?我們可以斷點一下,看看拿到的log對象是什麼,然後再看看log對象是怎麼産生的即可。

2,可以看到,get到的log對象是jul

Spring5新特性之日志體系
Spring5新特性之日志體系
static {
        logApi = LogFactory.LogApi.JUL;
        ClassLoader cl = LogFactory.class.getClassLoader();

        try {
            cl.loadClass("org.apache.logging.log4j.spi.ExtendedLogger");
            logApi = LogFactory.LogApi.LOG4J;
        } catch (ClassNotFoundException var6) {
            try {
                cl.loadClass("org.slf4j.spi.LocationAwareLogger");
                logApi = LogFactory.LogApi.SLF4J_LAL;
            } catch (ClassNotFoundException var5) {
                try {
                    cl.loadClass("org.slf4j.Logger");
                    logApi = LogFactory.LogApi.SLF4J;
                } catch (ClassNotFoundException var4) {
                    ;
                }
            }
        }
    }
           

上圖及代碼為spring-jcl的logFactory中的兩處核心代碼:

首先在初始化logFactory的時候,會去執行一個static的代碼塊,代碼也比較簡單,主要就是設定我們的logApi,預設是jul,然後依次用log4j2,slf4j-LAL,slf4j去反射判斷是否存在對應依賴,如果有則設定logApi為對應值,否則進入catch中繼續判斷。

然後再getlog的時候,則根據logApi去擷取log對象,代碼也比較容易了,就是個switch-case,預設是我們的jul來實作。

結合我上篇文章的jcl的實作,發現還是有很大差別的,jcl是封裝了一個靜态數組,然後依次循環周遊反射,成功則傳回對應實作。

原來在spring5的時候,他将jcl給改了,也就是我們的spring-jcl(畢竟大廠,牛逼),然後預設采用了jul來做日志輸出了。同時呢還支援slf4j,有着更好的擴充性和相容性。

好了,關于spring5的日志就說到這裡了。謝謝大家