本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到個人倉庫裏查看html
喜歡的話麻煩點下Star哈java
文章首發於個人我的博客:python
www.how2playlife.comandroid
本文是微信公衆號【Java技術江湖】的《走進JavaWeb技術世界》其中一篇,本文部份內容來源於網絡,爲了把本文主題講得清晰透徹,也整合了不少我認爲不錯的技術博客內容,引用其中了一些比較好的博客文章,若有侵權,請聯繫做者。git
該系列博文會告訴你如何從入門到進階,從servlet到框架,從ssm再到SpringBoot,一步步地學習JavaWeb基礎知識,並上手進行實戰,接着瞭解JavaWeb項目中常常要使用的技術和組件,包括日誌組件、Maven、Junit,等等內容,以便讓你更完整地瞭解整個JavaWeb技術體系,造成本身的知識框架。程序員
若是對本系列文章有什麼建議,或者是有什麼疑問的話,也能夠關注公衆號【Java技術江湖】聯繫做者,歡迎你參與本系列博文的創做和修訂。github
文末贈送8000G的Java架構師學習資料,須要的朋友能夠到文末了解領取方式,資料包括Java基礎、進階、項目和架構師等免費學習資料,更有數據庫、分佈式、微服務等熱門技術學習視頻,內容豐富,兼顧原理和實踐,另外也將贈送做者原創的Java學習指南、Java程序員面試指南等乾貨資源)
web
咱們先看一個故事。項目經理A帶着一幫兄弟開發了一套複雜的企業ERP系統,這個系統一連開發了好幾年,開發人員也換了好幾撥。面試
最開始的時候,項目經理A安排小B在系統中添加日誌功能,在控制檯上打印一些必要的信息。最開始的時候,因爲項目的功能比較少,因而小B就是用System.out.println的方式打印日誌信息。經理A感受這樣使用比較方便,也便於項目小組人員的使用,因而就沿用了下來。
此時小B被借調到其餘項目,小C加入到了項目組中。此時項目經理A要求改造日誌系統,要求能把日誌寫到一個文件中,方便之後分析用戶行爲。小C在查看了之前的日誌方式以後,感受特別low,因而本身寫了一個日誌框架,命名爲xiaoC-logging.jar,此舉收到了項目經理A的好評。
項目組中加入了一個大牛老D,老D發現xiaoC-logging.jar這個日誌框架雖然能夠知足基本的日誌要求,可是還不夠高大上,沒有一些諸如自動歸檔,異步寫入文件,把日誌文件寫入NoSQL數據庫中等功能。因而老D開發了一個更高級的日誌框架叫oldD-logging.jar。
oldD-logging.jar開發完成以後,須要把原來的xiaoC-logging.jar中的日誌API作修改,把以前的日誌實現寫下來,換上高大上的oldD-logging.jar。
在這個卸載與上新的過程當中,老D的工做量陡增,他感受很累。不過姜仍是老的辣,他參考了JDBC和spring中面向接口的編程方式,制定了一個日誌的門面(一系列的接口),之後全部的日誌的記錄,都只面向接口編程,至於從此怎麼去實現,都要遵循這個接口就能夠了。
那麼在JAVA開發中,這正的日誌系統是怎麼演變的呢?簡短地描述下日誌發展,最早出現的是apache開源社區的log4j,這個日誌確實是應用最普遍的日誌工具,成爲了java日誌的事實上的標準。然而,當時Sun公司在jdk1.4中增長了JUL日誌實現,企圖對抗log4j,可是卻形成了混亂,這個也是被人詬病的一點。固然也有其餘日誌工具的出現,這樣必然形成開發者的混亂,由於這些日誌系統互相沒有關聯,替換和統一也就變成了比較棘手的一件事。想象下你的應用使用log4j,而後使用了一個其餘團隊的庫,他們使用了JUL,你的應用就得使用兩個日誌系統了,而後又有第二個庫出現了,使用了simplelog。
這個時候估計讓你崩潰了,這是要鬧哪樣?這個情況交給你來想一想辦法,你該如何解決呢?進行抽象,抽象出一個接口層,對每一個日誌實現都適配或者轉接,這樣這些提供給別人的庫都直接使用抽象層便可。不錯,開源社區提供了commons-logging抽象,被稱爲JCL,也就是日誌框架了,確實出色地完成了兼容主流的日誌實現(log4j、JUL、simplelog),基本一統江湖,就連頂頂大名的spring也是依賴了JCL。
看起來事物確實是美好,可是美好的日子不長,接下來另外一個優秀的日誌框架slf4j的加入致使了更加混亂的場面。比較巧的是slf4j的做者(Ceki Gülcü)就是log4j的做者,他以爲JCL不夠優秀,因此他要本身搞一套更優雅的出來,因而slf4j日誌體系誕生了,併爲slf4j實現了一個親子——logback,確實更加優雅,可是因爲以前不少代碼庫已經使用JCL,雖然出現slf4j和JCL之間的橋接轉換,可是集成的時候問題依然多多,對不少新手來講確實會很懊惱,由於比單獨的log4j時代「複雜」多了,抱怨聲確實不少。
到此原本應該完了,可是Ceki Gülcü以爲仍是得回頭拯救下本身的「大阿哥」——log4j,因而log4j2誕生了,一樣log4j2也參與到了slf4j日誌體系中,想必未來會更加混亂。接下來詳細解讀日誌系統的配合使用問題。slf4j的設計確實比較優雅,採用比較熟悉的方式——接口和實現分離,有個純粹的接口層——slf4j-api工程,這個裏邊基本徹底定義了日誌的接口,因此對於開發來講,只須要使用這個便可。
有接口就要有實現,比較推崇的實現是logback,logback徹底實現了slf4j-api的接口,而且性能也比log4j更好,同時實現了變參佔位符日誌輸出方式等等新特性。剛剛也提到log4j的使用比較廣泛,因此支持這批用戶依然是必須的,slf4j-log4j12也實現了slf4j-api,這個算是對log4j的適配器。一樣推理,也會有對JUL的適配器slf4j-jdk14等等。爲了使使用JCL等等其餘日誌系統後者實現的用戶能夠很簡單地切換到slf4j上來,給出了各類橋接工程,好比:jcl-over-slf4j會把對JCL的調用都橋接到slf4j上來,能夠看出jcl-over-slf4j的api和JCL是相同的,因此這兩個jar是不能共存的。jul-to-slf4j是把對jul的調用橋接到slf4j上,log4j-over-slf4j是把對log4j的調用橋接到slf4j。
要搞清楚它們的關係,就要從它們是在什麼狀況下產生的提及。咱們按照時間的前後順序來介紹。
在JDK 1.3及之前,Java打日誌依賴System.out.println(), System.err.println()或者e.printStackTrace(),Debug日誌被寫到STDOUT流,錯誤日誌被寫到STDERR流。這樣打日誌有一個很是大的缺陷,即沒法定製化,且日誌粒度不夠細。
因而, Gülcü 於2001年發佈了Log4j,後來成爲Apache 基金會的頂級項目。Log4j 在設計上很是優秀,對後續的 Java Log 框架有長久而深遠的影響,它定義的Logger、Appender、Level等概念現在已經被普遍使用。Log4j 的短板在於性能,在Logback 和 Log4j2 出來以後,Log4j的使用也減小了。
受Logj啓發,Sun在Java1.4版本中引入了java.util.logging,可是j.u.l功能遠不如log4j完善,開發者須要本身編寫Appenders(Sun稱之爲Handlers),且只有兩個Handlers可用(Console和File),j.u.l在Java1.5之後性能和可用性纔有所提高。
因爲項目的日誌打印必然選擇兩個框架中至少一個,這時候,Apache的JCL(commons-logging)誕生了。JCL 是一個Log Facade,只提供 Log API,不提供實現,而後有 Adapter 來使用 Log4j 或者 JUL 做爲Log Implementation。
在程序中日誌建立和記錄都是用JCL中的接口,在真正運行時,會看當前ClassPath中有什麼實現,若是有Log4j 就是用 Log4j, 若是啥都沒有就是用 JDK 的 JUL。
這樣,在你的項目中,還有第三方的項目中,你們記錄日誌都使用 JCL 的接口,而後最終運行程序時,能夠按照本身的需求(或者喜愛)來選擇使用合適的Log Implementation。若是用Log4j, 就添加 Log4j 的jar包進去,而後寫一個 Log4j 的配置文件;若是喜歡用JUL,就只須要寫個 JUL 的配置文件。若是有其餘的新的日誌庫出現,也只須要它提供一個Adapter,運行的時候把這個日誌庫的 jar 包加進去。
不過,commons-logging對Log4j和j.u.l的配置問題兼容的並很差,使用commons-loggings還可能會遇到類加載問題,致使NoClassDefFoundError的錯誤出現。
到這個時候一切看起來都很簡單,很美好。接口和實現作了良好的分離,在統一的JCL之下,不改變任何代碼,就能夠經過配置就換用功能更強大,或者性能更好的日誌庫實現。
這種簡單美好一直持續到SLF4J出現。
SLF4J(Simple Logging Facade for Java)和 Logback 也是Gülcü 創立的項目,目的是爲了提供更高性能的實現。
從設計模式的角度說,SLF4J 是用來在log和代碼層之間起到門面做用,相似於 JCL 的 Log Facade。對於用戶來講只要使用SLF4J提供的接口,便可隱藏日誌的具體實現,SLF4J提供的核心API是一些接口和一個LoggerFactory的工廠類,用戶只需按照它提供的統一紀錄日誌接口,最終日誌的格式、紀錄級別、輸出方式等可經過具體日誌系統的配置來實現,所以能夠靈活的切換日誌系統。
Logback是log4j的升級版,當前分爲三個目標模塊:
Logback相較於log4j有更多的優勢:
更詳細的解釋參見官網:https://logback.qos.ch/reasonsToSwitch.html
到這裏,你可能會問:Apache 已經有了個JCL,用來作各類Log lib統一的接口,若是 Gülcü 要搞一個更好的 Log 實現的話,直接寫一個實現就行了,爲啥還要搞一個和SLF4J呢?
緣由是Gülcü 認爲 JCL 的 API 設計得很差,容易讓使用者寫出性能有問題的代碼。關於這點,你能夠參考這篇文章得到更詳細的介紹:https://zhuanlan.zhihu.com/p/24272450
如今事情就變複雜了。咱們有了兩個流行的 Log Facade,以及三個流行的 Log Implementation。Gülcü 是個追求完美的人,他決定讓這些Log之間都可以方便的互相替換,因此作了各類 Adapter 和 Bridge 來鏈接:
能夠看到甚至 Log4j 和 JUL 均可以橋接到SLF4J,再經過 SLF4J 適配到到 Logback!須要注意的是不能有循環的橋接,好比下面這些依賴就不能同時存在:
然而,事情在變得更麻煩!
Log4j2
如今有了更好的 SLF4J 和 Logback,慢慢取代JCL 和 Log4j ,事情到這裏總該大統一圓滿結束了吧。然而維護 Log4j 的人不這樣想,他們不想坐視用戶一點點被 SLF4J / Logback 蠶食,繼而搞出了 Log4j2。
Log4j2 和 Log4j1.x 並不兼容,設計上很大程度上模仿了 SLF4J/Logback,性能上也得到了很大的提高。Log4j2 也作了 Facade/Implementation 分離的設計,分紅了 log4j-api 和 log4j-core。
如今好了,咱們有了三個流行的Log 接口和四個流行的Log實現,若是畫出橋接關係的圖來回事什麼樣子呢?
看到這裏是否是感受有點暈呢?是的,我也有這種感受。一樣,在添加依賴的時候,要當心不要有循環依賴。
http://www.javashuo.com/article/p-ohvhntlc-ke.html
http://www.javashuo.com/article/p-tfbleich-bp.html
http://c.biancheng.net/view/939.html
https://blog.csdn.net/android_hl/article/details/53228348
黃小斜是 985 碩士,阿里巴巴Java工程師,在自學編程、技術求職、Java學習等方面有豐富經驗和獨到看法,但願幫助到更多想要從事互聯網行業的程序員們。
做者專一於 JAVA 後端技術棧,熱衷於分享程序員乾貨、學習經驗、求職心得,以及自學編程和Java技術棧的相關乾貨。
黃小斜是一個斜槓青年,堅持學習和寫做,相信終身學習的力量,但願和更多的程序員交朋友,一塊兒進步和成長!
原創電子書:
關注微信公衆號【程序員黃小斜】後回覆【原創電子書】便可領取我原創的電子書《菜鳥程序員修煉手冊:從技術小白到阿里巴巴Java工程師》這份電子書總結了我2年的Java學習之路,包括學習方法、技術總結、求職經驗和麪試技巧等內容,已經幫助不少的程序員拿到了心儀的offer!
程序員3T技術學習資源: 一些程序員學習技術的資源大禮包,關注公衆號後,後臺回覆關鍵字 「資料」 便可免費無套路獲取,包括Java、python、C++、大數據、機器學習、前端、移動端等方向的技術資料。
若是你們想要實時關注我更新的文章以及分享的乾貨的話,能夠關注個人微信公衆號【Java技術江湖】
這是一位阿里 Java 工程師的技術小站。做者黃小斜,專一 Java 相關技術:SSM、SpringBoot、MySQL、分佈式、中間件、集羣、Linux、網絡、多線程,偶爾講點Docker、ELK,同時也分享技術乾貨和學習經驗,致力於Java全棧開發!
Java工程師必備學習資源:
關注公衆號後回覆」Java「便可領取 Java基礎、進階、項目和架構師等免費學習資料,更有數據庫、分佈式、微服務等熱門技術學習視頻,內容豐富,兼顧原理和實踐,另外也將贈送做者原創的Java學習指南、Java程序員面試指南等乾貨資源
黃小斜是 985 碩士,阿里巴巴Java工程師,在自學編程、技術求職、Java學習等方面有豐富經驗和獨到看法,但願幫助到更多想要從事互聯網行業的程序員們。
做者專一於 JAVA 後端技術棧,熱衷於分享程序員乾貨、學習經驗、求職心得,以及自學編程和Java技術棧的相關乾貨。
黃小斜是一個斜槓青年,堅持學習和寫做,相信終身學習的力量,但願和更多的程序員交朋友,一塊兒進步和成長!
原創電子書:
關注微信公衆號【程序員黃小斜】後回覆【原創電子書】便可領取我原創的電子書《菜鳥程序員修煉手冊:從技術小白到阿里巴巴Java工程師》這份電子書總結了我2年的Java學習之路,包括學習方法、技術總結、求職經驗和麪試技巧等內容,已經幫助不少的程序員拿到了心儀的offer!
程序員3T技術學習資源: 一些程序員學習技術的資源大禮包,關注公衆號後,後臺回覆關鍵字 「資料」 便可免費無套路獲取,包括Java、python、C++、大數據、機器學習、前端、移動端等方向的技術資料。
若是你們想要實時關注我更新的文章以及分享的乾貨的話,能夠關注個人微信公衆號【Java技術江湖】
這是一位阿里 Java 工程師的技術小站。做者黃小斜,專一 Java 相關技術:SSM、SpringBoot、MySQL、分佈式、中間件、集羣、Linux、網絡、多線程,偶爾講點Docker、ELK,同時也分享技術乾貨和學習經驗,致力於Java全棧開發!
Java工程師必備學習資源:
關注公衆號後回覆」Java「便可領取 Java基礎、進階、項目和架構師等免費學習資料,更有數據庫、分佈式、微服務等熱門技術學習視頻,內容豐富,兼顧原理和實踐,另外也將贈送做者原創的Java學習指南、Java程序員面試指南等乾貨資源