日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
阿里巴巴開(kāi)發(fā)手冊(cè)強(qiáng)制使用SLF4J作為門(mén)面擔(dān)當(dāng)?shù)拿孛?,我搞清楚?/div>

之前已經(jīng)詳細(xì)、全面地介紹了 Log4j,相信小伙伴們已經(jīng)完全掌握了。那我在讀嵩山版的阿里巴巴開(kāi)發(fā)手冊(cè)(沒(méi)有的小伙伴,記著找我要)的時(shí)候,就發(fā)現(xiàn)了一條「強(qiáng)制」性質(zhì)的日志規(guī)約:

成都創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),新干企業(yè)網(wǎng)站建設(shè),新干品牌網(wǎng)站建設(shè),網(wǎng)站定制,新干網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷(xiāo),網(wǎng)絡(luò)優(yōu)化,新干網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M(mǎn)足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專(zhuān)業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶(hù)成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。

應(yīng)用中不可以直接使用日志系統(tǒng)(Log4j、Logback)中的 API,而應(yīng)該使用日志框架中的 API,比如說(shuō) SLF4J,使用門(mén)面模式的日志框架,有利于維護(hù)和統(tǒng)一各個(gè)類(lèi)的日志處理方式。

(為什么我把這段文字手敲了下來(lái)呢,因?yàn)槲野l(fā)現(xiàn)阿里巴巴開(kāi)發(fā)手冊(cè)上的有語(yǔ)病,瞧下面紅色標(biāo)出的部分)

(維護(hù)和統(tǒng)一,把統(tǒng)一放在最后面讀起來(lái)真的是別扭,和的有點(diǎn)牽強(qiáng),請(qǐng)問(wèn)手冊(cè)的小編是數(shù)學(xué)老師教的語(yǔ)文吧?)

那看到這條強(qiáng)制性的規(guī)約,我就忍不住想要問(wèn):“為什么阿里巴巴開(kāi)發(fā)手冊(cè)會(huì)強(qiáng)制使用 SLF4J 作為 Log4J 的門(mén)面擔(dān)當(dāng)呢?”究竟這背后藏了什么“不可告人”的秘密?

(請(qǐng)小伙伴們自行配上 CCTV 12 臺(tái)的那種 BGM)

PS:順帶給小伙伴們普及一點(diǎn)小知識(shí),阿里巴巴開(kāi)發(fā)手冊(cè)上出現(xiàn)的 Jakarta 其實(shí)是 Apache 軟件基金會(huì)下的一個(gè)開(kāi)源項(xiàng)目。其實(shí) Commons 是以前隸屬于 Jakarta,現(xiàn)在是作為 Apache 下的一個(gè)單獨(dú)項(xiàng)目,阿里巴巴開(kāi)發(fā)手冊(cè)上的描述已經(jīng)不太恰當(dāng)了,換成是 Apache Commons Logging 會(huì)更合適一點(diǎn)。

(忍不住又給阿里巴巴開(kāi)發(fā)手冊(cè)挑了一個(gè)毛病,請(qǐng)?jiān)徫摇耙唤z不茍”的做事態(tài)度)

01、SLF4J 是什么

SLF4J 是 Simple Logging Facade for Java 的縮寫(xiě)(for≈4),也就是簡(jiǎn)易的日志門(mén)面,以外觀模式(Facade pattern,一種設(shè)計(jì)模式,為子系統(tǒng)中的一組接口提供一個(gè)統(tǒng)一的高層接口,使得子系統(tǒng)更容易使用)實(shí)現(xiàn),支持 java.util.logging、Log4J 和 Logback。

SLF4J 的作者就是 Log4J 和 Logback 的作者,他的 GitHub 主頁(yè)長(zhǎng)下面這樣:

一股秋風(fēng)瑟瑟的清冷感撲面而來(lái),有沒(méi)有?可能巨佬不屑于維護(hù)他的 GitHub 主頁(yè)吧?我的 GitHub 主頁(yè)夠凄慘了,沒(méi)想到巨佬比我還慘,終于可以吹牛逼地說(shuō),“我,沉默王二,GitHub 主頁(yè)比 SLF4J、Log4J 和 Logback 的作者 Ceki Gulcu 綠多了。。。。。?!?/p>

1996 年初,歐洲安全電子市場(chǎng)項(xiàng)目決定編寫(xiě)自己的跟蹤 API,最后該 API 演變成了 Log4j,已經(jīng)推出就備受寵愛(ài)。

2002 年 2 月,Sun 推出了自己的日志包 java.util.logging(可稱(chēng) JUL),據(jù)說(shuō)實(shí)現(xiàn)思想借鑒了 Log4j,畢竟此時(shí)的 Log4j 已經(jīng)很成熟了。

2002 年 8 月,Apache 就推出了自己的日志包,也就是阿里巴巴開(kāi)發(fā)手冊(cè)上提到的 JCL(Jakarta Commons Logging)。JCL 的野心很大,它在 JUL 和 Log4j 的基礎(chǔ)上提供了一個(gè)抽象層的接口,方便使用者在 JUL 和 Log4j 之間切換。

但 JCL 好像并不怎么招人喜歡,有人是這樣抱怨的:

Ceki Gulcu 也覺(jué)得 JCL 不好,要不然他也不會(huì)在 2005 年自己擼一個(gè)名叫 SLF4J 的新項(xiàng)目,對(duì)吧?但出來(lái)混總是要付出代價(jià)的,SLF4J 只有接口,沒(méi)有實(shí)現(xiàn),總不能強(qiáng)逼著 Java 和 Apache 去實(shí)現(xiàn) SLF4J 接口吧?這太難了,不現(xiàn)實(shí)。

但巨佬之所以稱(chēng)之為巨佬,是因?yàn)樗麚碛谐銎胀ㄈ说捏@人之處,他在 SLF4J 和 JUL、Log4j、JCL 之間搭了三座橋:

巨佬動(dòng)手,豐衣足食,有沒(méi)有?狠起來(lái)連自己的 Log4j 都搭個(gè)橋。

面對(duì)巨佬的霸氣,我只想弱弱地說(shuō)一句,“ SLF4J 這個(gè)門(mén)面擔(dān)當(dāng),你以為好當(dāng)?shù)陌?”

02、SLF4J 解決了什么痛點(diǎn)

春秋戰(zhàn)國(guó)的時(shí)候,每個(gè)國(guó)家都有自己的貨幣,用別國(guó)的貨幣也不合適,對(duì)吧?那在發(fā)生貿(mào)易的時(shí)候就比較麻煩了,貨幣不統(tǒng)一,就沒(méi)法直接交易,因?yàn)樨泿趴赡懿坏葍r(jià)。

那秦始皇統(tǒng)一六國(guó)后,就推出了新的貨幣政策,全國(guó)都用一種貨幣,那之前的問(wèn)題就解決掉了。

你看,同樣的道理,日志系統(tǒng)有 JUL、JCL,Ceki Gulcu 自己又寫(xiě)了 2 種,Log4j 和 Logback,各有各的優(yōu)缺點(diǎn),再加上使用者千千萬(wàn),蘿卜白菜各有所愛(ài),這就導(dǎo)致不同的應(yīng)用可能會(huì)用不同的日志系統(tǒng)。

假設(shè)我們正在開(kāi)發(fā)一套系統(tǒng),打算用 SLF4J 作為門(mén)面,Log4j 作為日志系統(tǒng),我們?cè)陧?xiàng)目中使用了 A 框架,而 A 框架的門(mén)面是 JCL,日志系統(tǒng)是 JUL,那就相等于要維護(hù)兩套日志系統(tǒng),對(duì)吧?

這就難受了!

Ceki Gulcu 想到了這個(gè)問(wèn)題,并且?guī)臀覀兘鉀Q了!來(lái)看 SLF4J 官網(wǎng)給出的解決方案。

  • 使用 jcl-over-slf4j.jar 替換 commons-logging.jar
  • 引入 jul-to-slf4j.jar

為了模擬這個(gè)過(guò)程,我們來(lái)建一個(gè)使用 JCL 的項(xiàng)目。

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

 
 
 
 
  1.     commons-logging
  2.     commons-logging
  3.     1.2

第二步,新建測(cè)試類(lèi):

 
 
 
 
  1. package com.itwanger;
  2. import org.apache.commons.logging.Log;
  3. import org.apache.commons.logging.LogFactory;
  4. /**
  5.  * @author 微信搜「沉默王二」,回復(fù)關(guān)鍵字 PDF
  6.  */
  7. public class Demo {
  8.     private static Log logger = LogFactory.getLog(Demo.class);
  9.     public static void main(String[] args) {
  10.         logger.info("jcl");
  11.     }
  12. }

該類(lèi)會(huì)通過(guò) LogFactory 獲取一個(gè) Log 對(duì)象,并且使用 info() 方法打印一行日志。

調(diào)試這段代碼的過(guò)程中你會(huì)發(fā)現(xiàn),Log 的實(shí)現(xiàn)有四種:

如果沒(méi)有綁定 Log4j 的話(huà),就會(huì)默認(rèn)選擇 Jdk14Logger——它返回的 Logger 對(duì)象,正是 java.util.logging.Logger,也就是 JUL。

因此,就可以在控制臺(tái)看到以下信息:

 
 
 
 
  1. 10月 21, 2020 3:13:30 下午 com.itwanger.Demo main
  2. 信息: jcl

怎么把使用 JCL 的項(xiàng)目改造成使用 SLF4J 的呢?

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

 
 
 
 
  1.     org.slf4j
  2.     jcl-over-slf4j
  3.     1.7.25
  4.     org.slf4j
  5.     jul-to-slf4j
  6.     1.7.29
  7.     org.slf4j
  8.     slf4j-log4j12
  9.     1.7.25

第四步,在 resources 目錄下創(chuàng)建 log4j.properties 文件,內(nèi)容如下所示:

 
 
 
 
  1. ### 設(shè)置###
  2. log4j.rootLogger = debug,stdout,D
  3. ### 輸出信息到控制臺(tái) ###
  4. log4j.appender.stdout = org.apache.log4j.ConsoleAppender
  5. log4j.appender.stdout.Target = System.out
  6. log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
  7. log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
  8. ### 輸出DEBUG 級(jí)別以上的日志到=debug.log ###
  9. log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
  10. log4j.appender.D.File = debug.log
  11. log4j.appender.D.Append = true
  12. log4j.appender.D.Threshold = DEBUG 
  13. log4j.appender.D.layout = org.apache.log4j.PatternLayout
  14. log4j.appender.D.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

再次運(yùn)行 Demo 類(lèi),你會(huì)發(fā)現(xiàn) target 目錄下會(huì)生成一個(gè)名叫 debug.log 的文件,內(nèi)容如下所示:

 
 
 
 
  1. 2020-10-21 15:32:06  [ main:0 ] - [ INFO ]  jcl

并且可以在控制臺(tái)看到以下信息:

 
 
 
 
  1. [INFO ] 2020-10-21 15:32:06,192 method:com.itwanger.Demo.main(Demo.java:12)
  2. jcl

仔細(xì)對(duì)比一下,你就會(huì)發(fā)現(xiàn),這次輸出的格式和之前不一樣,這就是因?yàn)?Log4j 和 JUL 的日志格式不同導(dǎo)致的。

另外,你有沒(méi)有發(fā)現(xiàn)?我們并沒(méi)有改動(dòng)測(cè)試類(lèi) Demo,它里面使用的仍然是 JCL 獲取 Log 的方式:

 
 
 
 
  1. private static Log logger = LogFactory.getLog(Demo.class);

但輸出的格式已經(jīng)切換到 Log4j 了!

SLF4J 除了提供這種解決方案,綁定 Log4j 替換 JUL 和 JCL;還提供了綁定 Logback 替換 JUL、JCL、Log4j 的方案:

還有綁定 JUL 替換 JCL 和 Log4j 的方案:

太強(qiáng)了,有木有?有的話(huà)請(qǐng)?jiān)诹粞詤^(qū)敲出 666。

03、SLF4J 比 Log4J 強(qiáng)在哪

SLF4J 除了解決掉以上的痛點(diǎn),幫助我們的應(yīng)用程序獨(dú)立于任何特定的日志系統(tǒng),還有一個(gè)非常牛逼的功能,那就是 SLF4J 在打印日志的時(shí)候使用了占位符 {},它有點(diǎn)類(lèi)似于 String 類(lèi)的 format() 方法(使用 %s 等填充參數(shù)),但更加便捷,這在很大程度上提高了程序的性能。

眾所周知,字符串是不可變的,字符串拼接會(huì)創(chuàng)建很多不必要的字符串對(duì)象,極大的消耗了內(nèi)存空間。但 Log4J 在打印帶參數(shù)的日志時(shí),只能使用字符串拼接的方式:

 
 
 
 
  1. String name = "沉默王二";
  2. int age = 18;
  3. logger.debug(name + ",年紀(jì):" + age + ",是個(gè)非常不要臉的程序員");

非常笨重,但加入了 SLF4J 后,這個(gè)問(wèn)題迎刃而解。我們來(lái)看一下在 Log4j 項(xiàng)目中加入 SLF4J 的詳細(xì)的步驟。

第一步,把 log4j 的依賴(lài)替換為 slf4j-log4j12(Maven 會(huì)自動(dòng)引入 slf4j-api.jar 和 log4j.jar):

 
 
 
 
  1.     org.slf4j
  2.     slf4j-log4j12
  3.     1.7.25

第二步,在 resources 目錄下創(chuàng)建 log4j.properties 文件,內(nèi)容和 Log4j 那一篇完全相同:

 
 
 
 
  1. ### 設(shè)置###
  2. log4j.rootLogger = debug,stdout,D,E
  3. ### 輸出信息到控制臺(tái) ###
  4. log4j.appender.stdout = org.apache.log4j.ConsoleAppender
  5. log4j.appender.stdout.Target = System.out
  6. log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
  7. log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
  8. ### 輸出DEBUG 級(jí)別以上的日志到=debug.log ###
  9. log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
  10. log4j.appender.D.File = debug.log
  11. log4j.appender.D.Append = true
  12. log4j.appender.D.Threshold = DEBUG 
  13. log4j.appender.D.layout = org.apache.log4j.PatternLayout
  14. log4j.appender.D.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
  15. ### 輸出ERROR 級(jí)別以上的日志到=error.log ###
  16. log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
  17. log4j.appender.E.File =error.log 
  18. log4j.appender.E.Append = true
  19. log4j.appender.E.Threshold = ERROR 
  20. log4j.appender.E.layout = org.apache.log4j.PatternLayout
  21. log4j.appender.E.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

第三步,新建測(cè)試類(lèi):

 
 
 
 
  1. package com.itwanger;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. /**
  5.  * @author 微信搜「沉默王二」,回復(fù)關(guān)鍵字 PDF
  6.  */
  7. public class Log4jSLF4JDemo {
  8.     private static final Logger logger = LoggerFactory.getLogger(Log4jSLF4JDemo.class);
  9.     public static void main(String[] args) {
  10.         logger.debug("{},是個(gè)非常不要臉的程序員","沉默王二");
  11.     }
  12. }

看到了吧,使用占位符要比“+”操作符方便的多。并且此時(shí)不再需要 isDebugEnabled() 先進(jìn)行判斷,debug() 方法會(huì)在字符串拼接之前執(zhí)行。

如果只是 Log4J 的話(huà),會(huì)先進(jìn)行字符串拼接,再執(zhí)行 debug() 方法,來(lái)看示例代碼:

 
 
 
 
  1. String name = "沉默王二";
  2. int age = 18;
  3. logger.debug(name + ",年紀(jì):" + age + ",是個(gè)非常不要臉的程序員");

在調(diào)試這段代碼的時(shí)候,你會(huì)發(fā)現(xiàn)的,如下圖所示:

這也就意味著,如果日志系統(tǒng)的級(jí)別不是 DEBUG,就會(huì)多執(zhí)行了字符串拼接的操作,白白浪費(fèi)了性能。

注意,阿里巴巴開(kāi)發(fā)手冊(cè)上還有一條「強(qiáng)制」級(jí)別的規(guī)約:

這是因?yàn)槿绻麉?shù)是基本數(shù)據(jù)類(lèi)型的話(huà),會(huì)先進(jìn)行自動(dòng)裝箱(Integer.valueOf())。測(cè)試代碼如下所示:

 
 
 
 
  1. logger.debug("沉默王二,{}歲", 18);

通過(guò)反編譯工具就可以看得到:

 
 
 
 
  1. logger.debug("\u6C89\u9ED8\u738B\u4E8C\uFF0C{}\u5C81", Integer.valueOf(18));

如果參數(shù)需要調(diào)用其他方法的話(huà),debug() 方法會(huì)隨后調(diào)用。

也就是說(shuō),如果不 isDebugEnabled() 的話(huà),在不是 DEBUG 級(jí)別的情況下,會(huì)多執(zhí)行自動(dòng)裝箱和調(diào)用其他方法的操作——程序的性能就下降了!

測(cè)試類(lèi)運(yùn)行的結(jié)果和之前 Log4J 的一樣,小伙伴們可以點(diǎn)擊鏈接跳轉(zhuǎn)到 Log4j 那篇對(duì)比下。

04、總結(jié)

簡(jiǎn)單總結(jié)一下這篇文章哈。

1)在使用日志系統(tǒng)的時(shí)候,一定要使用 SLF4J 作為門(mén)面擔(dān)當(dāng)。

2)SLF4J 可以統(tǒng)一日志系統(tǒng),作為上層的抽象接口,不需要關(guān)注底層的日志實(shí)現(xiàn),可以是 Log4j,也可以是 Logback,或者 JUL、JCL。

3)SLF4J 在打印日志的時(shí)候可以使用占位符,既提高了程序性能(臨時(shí)字符串少了,垃圾回收的工作量就小),又讓代碼變得美觀統(tǒng)一。

本文轉(zhuǎn)載自微信公眾號(hào)「沉默王二」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系沉默王二公眾號(hào)。


當(dāng)前名稱(chēng):阿里巴巴開(kāi)發(fā)手冊(cè)強(qiáng)制使用SLF4J作為門(mén)面擔(dān)當(dāng)?shù)拿孛埽腋闱宄?
文章源于:http://www.5511xx.com/article/dpoiijc.html