使用slf4j盡管很方便,但是讓很多人搞不明白slf4j那么多包怎么用。
其實(shí)slf4j原理很簡(jiǎn)單,他只提供一個(gè)核心slf4j api(就是slf4j-api.jar包),這個(gè)包只有日志的接口,并沒有實(shí)現(xiàn),所以如果要使用就得再給它提供一個(gè)實(shí)現(xiàn)了些接口的日志包,比 如:log4j,common logging,jdk log日志實(shí)現(xiàn)包等,但是這些日志實(shí)現(xiàn)又不能通過接口直接調(diào)用,實(shí)現(xiàn)上他們根本就和slf4j-api不一致,因此slf4j又增加了一層來轉(zhuǎn)換各日志實(shí)現(xiàn)包的使 用,當(dāng)然slf4j-simple除外。其結(jié)構(gòu)如下:
slf4j-api(接口層)
|
各日志實(shí)現(xiàn)包的連接層( slf4j-jdk14, slf4j-log4j)
|
各日志實(shí)現(xiàn)包
下面這個(gè)圖更能說明其原理:
在這里還需要注意的是,連接層的jar包和實(shí)現(xiàn)的jar的版本要一致。
附j(luò)ar說明:
slf4j-api-1.6.1.jar --> slf4j核心接口包
slf4j-simple-1.6.1.jar --> slf4j Simple Logger日志實(shí)現(xiàn)包
slf4j-nop-1.6.1.jar -->
slf4j-migrator-1.6.1.jar -->
slf4j-log4j12-1.6.1.jar --> slf4j調(diào)用log4j的實(shí)現(xiàn)包
slf4j-jdk14-1.6.1.jar --> slf4j調(diào)用jdk java.util.logging的實(shí)現(xiàn)包
slf4j-jcl-1.6.1.jar --> Jakarta Commons Logging
slf4j-ext-1.6.1.jar -->
log4j-over-slf4j-1.6.1.jar -->
jul-to-slf4j-1.6.1.jar -->
jcl-over-slf4j-1.6.1.jar -->
slf4j+log4j組合使用模式:
1. slf4j-api-1.5.11.jar
2. slf4j-log4j12-1.5.11.jar
3. log4j-1.2.15.jar
4. log4j.properties(也可以是 log4j.xml,本例中用 log4j.propertes)
JCL+Log4J組合使用模式:
1. commons-logging-1.1.jar
2. log4j-1.2.15.jar
3. log4j.properties
把這種 SLF4J+Log4J 的使用模式與曾為霸主地位的 JCL+Log4J 的用法進(jìn)行一下對(duì)比(請(qǐng)忽略掉包文件中的版本號(hào)):
SLF4J+Log4j 組合 對(duì)比 JCL+Log4J 組合
slf4j-api-1.5.11.jar 相當(dāng),定義高層 API commons-logging-1.1.jar
slf4j-log4j12-1.5.11.jar 相當(dāng),左邊是用綁定包,右邊
是用配置文件來指定日志實(shí)現(xiàn) commons-logging.properties,內(nèi)容為:
org.apache.commons.logging.LogFactory=
org.apache.commons.logging.impl.LogFactoryImpl
或者
org.apache.commons.logging.Log=
org.apache.commons.logging.impl.Log4JLogger
log4j-1.2.15.jar 一樣 log4j-1.2.15.jar
log4j.properties 一樣,原來怎么配置現(xiàn)在也是 log4j.properties
程序代碼中:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Logger logger = LoggerFactory.getLogger(TestSlf4j.class);
logger.info("Hello {}","SLF4J"); 左邊侵入的是 SLF4J API,右邊是被 JCL 的 API 污染了
SLF4J 支持參數(shù)化,而 JCL 不能 程序代碼中:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Log log = LogFactory.getLog(TestJCL.class);
log.info("Hello JCL");
從上面的對(duì)比來看,SLF4j+Log4j 與 JCL+Log4J 的使用方式差不多,主要差異就在 SLF4J 用 jar 來告知用哪種日志實(shí)現(xiàn),而 JCL 是通過配置文件來獲得該選擇哪個(gè)日志實(shí)現(xiàn)。
為什么會(huì)興起 SLF4J,看看我們?cè)瓉砟囊粋€(gè)框架中,大的如 SSH 三雄(Spring、Struts、Hibernate),還有 WAS 應(yīng)用服務(wù)器,小的就不計(jì)其數(shù)以前用的通用日志框架都清一色的 Jakarta Commons Logging(JCL),日志實(shí)現(xiàn)會(huì)選用 Log4j,為何現(xiàn)在 Hibernate、Tapesty、DbUnit、Jetty V6 等紛紛變節(jié),都采用了 SLF4J 了呢?SLF4J 與 JCL 相比,定然是有其可表之處。而其中 SLF4J 受類加載器的影響較小,不易產(chǎn)生內(nèi)存溢出的問題,性能得到了改善,更主要是順應(yīng)了潮流的發(fā)展--可方便部署到 OSGI 環(huán)境中。