轉自:http://www.blogjava.net/daiyongzhi/archive/2014/04/13/412364.htmlhtml
common-logging是apache提供的一個通用的日誌接口。用戶能夠自由選擇第三方的日誌組件做爲具體實現,像log4j,或者jdk自帶的logging, common-logging會經過動態查找的機制,在程序運行時自動找出真正使用的日誌庫。固然,common-logging內部有一個Simple logger的簡單實現,可是功能很弱。因此使用common-logging,一般都是配合着log4j來使用。使用它的好處就是,代碼依賴是 common-logging而非log4j, 避免了和具體的日誌方案直接耦合,在有必要時,能夠更改日誌實現的第三方庫。java
slf4j全 稱爲Simple Logging Facade for JAVA,java簡單日誌門面。相似於Apache Common-Logging,是對不一樣日誌框架提供的一個門面封裝(是接口而非實現),能夠在部署的時候不修改任何配置便可接入一種日誌實現方案。可是,他在編譯時靜態綁定真正的Log庫。使用SLF4J時,若是你須要使用某一種日誌實現,那麼你必須選擇正確的SLF4J的jar包的集合(各類橋接包)。apache
使用slf4j的常見代碼:
編程
slf4j靜態綁定原理:SLF4J 會在編譯時會綁定import org.slf4j.impl.StaticLoggerBinder; 該類裏面實現對具體日誌方案的綁定接入。任何一種基於slf4j 的實現都要有一個這個類。如:org.slf4j.slf4j-log4j12-1.5.6: 提供對 log4j 的一種適配實現。api
注意:若是有任意兩個實現slf4j 的包同時出現,那麼就可能出現問題。
框架
幾乎在每一個jar包裏均可以看到log4j的身影,在多個子工程構成項目中,slf4j相關的衝突時不時就跳出來讓你不爽,那麼slf4j-api、slf4j-log4j12還有log4j他們是什麼關係?我把本身瞭解的和你們簡單分享一下:工具
slf4j:Simple Logging Facade for Java,爲java提供的簡單日誌Facade。Facade:門面,更底層一點說就是接口。他容許用戶以本身的喜愛,在工程中經過slf4j接入不一樣 的日誌系統。更直觀一點,slf4j是個數據線,一端嵌入程序,另外一端連接日誌系統,從而實現將程序中的信息導入到日誌系統並記錄。 性能
所以,slf4j入口就是衆多接口的集合,他不負責具體的日誌實現,只在編譯時負責尋找合適的日誌系統進行綁定。具體有哪些接口,所有都定義在slf4j-api中。查看slf4j-api源碼就能夠發現,裏面除了public final class LoggerFactory類以外,都是接口定義。所以,slf4j-api本質就是一個接口定義。this
下圖比較清晰的描述了他們之間的關係:url
當系統採用log4j做爲日誌框架實現的調用關係:
首先系統包含slf4j-api做爲日誌接入的接口;
at compile時slf4j-api中public final class LoggerFactor類中
private final static void bind() 方法會尋找具體的日誌實現類綁定,主要經過
StaticLoggerBinder.getSingleton();語句調用
slf4j-log4j12:連接slf4j-api和log4j中間的適配器。它實現了slf4j-apiz中StaticLoggerBinder接口,從而使得在編譯時綁定的是slf4j-log4j12的getSingleton()方法
log4j:這個是具體的日誌系統。經過slf4j-log4j12初始化Log4j,達到最終日誌的輸出。
============================================================================
本身的理解:
1)apache common-logging 和 slf4j 都是日誌接口,而非實現,雖然他們可能自帶有一個極簡的實現;
2)log4j、logback、還有 log4j2 等都是日誌記錄器的實現;
3)日誌接口如何查找日誌實現類庫: common-logging 經過動態綁定,到classpath去尋找;
slf4j 編譯時會靜態綁org.slf4j.impl.StaticLoggerBinder這個類,而其餘的日誌實現 log4j、logback 的實現中包括該類的實現,具體實現代碼就是綁定 本身的實現到 slf4j .
4)採用 slf4j 接口時,會涉及到 綁定器 和 橋接器 。slf4j-log4j12-version.jar 綁定 slf4j到log4j,jcl-over-slf4j 將採用jcl接口的日誌都橋接到slf4j接口,而後會採用slf4j的綁定器中綁定的日誌實現來記錄日誌。
5)使用 SLF4J 的比較典型搭配就是把 slf4j-api、JCL 橋接器、java.util.logging(JUL)橋接器、log4j 綁定器、log4j 這5個 jar 放置在 CLASS_PATH 裏。原理就是使用 slf4j 的各類橋接器,將全部日誌接口都橋接到 slf4j 這個接口,而後選擇一個具體的 slf4j 綁定器 和 日誌實現器,達到將全部日誌統一使用一個日誌實現器進行統一輸出的目的。
6)slf4j-api.jar 是slf4j自身的接口,common-logging.jar是接口,log4j.jar, logback.jar,log4j2.jar是實現;jcl-over-slf4j是jcl橋接到slf4j的jar包;slf4j-log4j.jar是slf4j綁定到log4j的jar包。
因此分爲:接口jar包、實現jar包、橋接到slf4j的jar包、slf4j綁定到實現的jar包。接口到接口是經過橋接包,接口到實現是經過綁定包。
7)最後給出兩個實例:
1> slf4j + log4j:
<!-- slf4j interface--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.6.1</version> </dependency> <!-- jcl bridge to slf4j --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.6.1</version> </dependency> <!-- slf4j binding to log4j --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.6.1</version> </dependency> <!-- log4j recorder --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
2> slf4j + logback 最簡形式:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.3</version> </dependency>
logback會自動引入 logback-core 和 slf4j:
3> slf4j + logback + jcl橋接:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.3</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.6.1</version> </dependency>
看起來 logback 配置確實比log4j要簡單得多。