小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

SLF4J 的幾種實(shí)際應(yīng)用模式--之三:JCL-Over-SLF4J+SLF4J

 CevenCheng 2010-09-08

SLF4J 的幾種實(shí)際應(yīng)用模式--之三:JCL-Over-SLF4J+SLF4J

(2010年04月07日) 發(fā)表于 Java博客

我們前面已經(jīng)講過了 SLF4J 的兩種用法:SLF4J+Log4J  和 SLF4J+Logback,那是在比較理想的情況下,所用組件只使用了 SLF4J 這一種統(tǒng)一日志框架的時(shí)候??墒?JCL 一直影響深遠(yuǎn),SLF4J 漸入佳境的時(shí)個(gè),在你的項(xiàng)目中很可能所用的組件,它們分別用了 JCL 和 SLF4J 兩種組件。比如說在項(xiàng)目中用了 Hibernate 3.5 和 Struts,或其他 Apache 的一些開源組件,你大約也不想用了 SLF4J 的組件日志信息輸出到 A 處,用了 JCL 的組件日志輸出到 B 處,那你自己寫的代碼中的日志信息該往哪兒寫呢? 

中國人一直都在追求大一統(tǒng),不喜歡城邦制而便于分而制之。但說到日志輸出還是得統(tǒng)一到單一通道中,一方面多個(gè)通道浪費(fèi)資源,另方面也便于配置和管理。那么既然 SLF4J 是趨勢,當(dāng) SLF4J 和 JCL 被丟到一個(gè)壇子里,首先會讓 SLF4J 為主,JCL 為輔,也就是要把 JCL 橋接到 SLF4J 上來,通過 SLF4J 統(tǒng)一輸出日志信息。于是也就是這篇要介紹的 SLF4J 使用模式:JCL-Over-SLF4J+SLF4J。 

從前面對 SLF4J 的認(rèn)識可知,即使把 JCL 轉(zhuǎn)嫁到 SLF4J,還是無法輸出日志,還需要一種日志實(shí)現(xiàn),下層該用 Log4J 還得用 Log4J,想用 Logback 還是要用 Logback。所以到了 SLF4J 后還得往下走,也就是前面那兩條路 SLF4J+Log4J 和 SLF4J+Logback,本篇使用 SLF4J 的模式具體就要分為: 

JCL-Over-SLF4J+ SLF4J+Log4J  和 JCL-Over-SLF4J+ SLF4J+Logback,這兩種實(shí)現(xiàn)方式差不多。只是分別用的 jar 包和配置文件不同,SLF4J+Log4J 和 SLF4J+Logback 原來要哪些文件現(xiàn)在還是需要那些文件,只是都要加上 jcl-over-slf4j-1.5.11.jar 包。這里說明 JCL-Over-SLF4J+ SLF4J+Logback 的方式。 

 需要的配置文件和組件包,下面四個(gè) jar 文件和一個(gè) xml文件都是要放在項(xiàng)目的 ClassPath 上。 

1. slf4j-api-1.5.11.jar 
2. logback-core-0.9.20.jar 
3. logback-classic-0.9.20.jar 
4. logback.xml 或 logback-test.xml 
5. jcl-over-slf4j-1.5.11.jar 

第 1 和第 5 個(gè)包在 http://www./download.html 處下載,第二第三個(gè)包在 http://logback./download.html 下載,可能包文件名中的版本號有些差異。 

下面是一個(gè)最簡單的 logback.xml 文件內(nèi)容 

 <?xml version="1.0" encoding="UTF-8"?>  

<configuration>  

  <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">  

      <encoder charset="GBK"> 

          <pattern>[Consociate] %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>  

      </encoder>

  </appender>  

   

  <root level="DEBUG">  

    <appender-ref ref="stdout" />  

  </root>  

</configuration> 

為了看看效果,我們在輸入的 pattern 中加入了 [Consociate],來檢驗(yàn)是否統(tǒng)一到單一的日志通道中去了。 

使用 了 JCL 和 SLF4J  的代碼 

package com.unmi;


import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;


public class TestJCLOverSlf4j {

//SLF4J 的 Logger

private static final Logger logger = LoggerFactory.getLogger("From SLF4J");

//JCL 的 Log

private static final Log log = LogFactory.getLog("From JCL");


//分別用上面的 logger 和 log 輸出日志,從輸出可以看到它們統(tǒng)一到一個(gè)通道中了

public static void main(String[] args) {

logger.info("Hello {}","From SLF4J");

log.info("Hello From JCL");

}

}

 

我們在上面代碼中,既使用了 JCL 統(tǒng)一日志框架,也使用了 SLF4J 的統(tǒng)一日志框架。要注意一點(diǎn),從 JCL 橋接過來的 log 不能輸出參數(shù)化消息了。上面代碼使用了 org.apache.commons.logging.Log,import org.apache.commons.logging.LogFactory,但你卻用不著引入 commons-logging.jar 包。 

執(zhí)行上面的代碼,看到輸出: 

[Consociate] 23:19:39.890 [main] INFO  From SLF4J - Hello From SLF4J 
[Consociate] 23:19:39.921 [main] INFO  From JCL - Hello From JCL 

很明顯示 JCL 框架和 SLF4J 框架的日志輸出都統(tǒng)一到了一個(gè)通道中來了,為什么呢? SLF4J 使用的是 Logback 輸出的信息,這一點(diǎn)沒問題的,而 JCL 是不認(rèn)識 Logback 的,所以 JCL 框架的輸出必然是繞道到 SLF4J,最后也是由 Logback 輸出的。 

實(shí)現(xiàn)分析: 

我們打開 jcl-over-slf4j-1.5.11.jar,看到里面有兩個(gè)包 org.apache.commons.logging 和 org.apache.commons.logging.impl,并有相應(yīng)的類,這就是為什么,雖然在代碼中有: 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 

卻不用把 commons-logging.jar 包引入到類路徑上的原因。 

再深入下 jcl-over-slf4j-1.5.11.jar,看到其中還有個(gè)文件 /META-INF/services/org.apache.commons.logging.LogFactory,內(nèi)容為: 

org.apache.commons.logging.impl.SLF4JLogFactory

# Axis gets at JCL through its own mechanism as defined by Commons Discovery, which 
# in turn follows the instructions found at: 
http://java./j2se/1.3/docs/guide/jar/jar.html#Service Provider 

JCL 運(yùn)行時(shí)使用了 SLF4JLogFactory,從而完成了 JCL 的日志實(shí)現(xiàn)委托給了 SLF4J,再由 SLF4J 進(jìn)一步完成具體的日志輸出。 

采用 JCL-Over-SLF4J+ SLF4J+Log4J 使用模式也是相似的,這里就不詳述了??偨Y(jié)下就是 JCL 把 SLF4J 當(dāng)作它的日志實(shí)現(xiàn)。 

再來想象個(gè)問題:如果我們把這兩個(gè)包 jcl-over-slf4j-1.5.11.jar 和 slf4j-jcl-1.5.11.jar 都放到 ClassPath 下會有什么情況呢?JCL 代理給 SLF4J,SLF4J 又綁定到 JCL,對了,死循環(huán),StackOverFlow 錯(cuò)誤: 

SLF4J: Detected both jcl-over-slf4j.jar AND slf4j-jcl.jar on the class path, preempting StackOverflowError. 
SLF4J: See also http://www./codes.html#jclDelegationLoop for more details. 
java.lang.ExceptionInInitializerError 
 at org.slf4j.impl.StaticLoggerBinder.<init>(StaticLoggerBinder.java:82) 
 at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:51) 
 at org.slf4j.LoggerFactory.getSingleton(LoggerFactory.java:230) 
 at org.slf4j.LoggerFactory.bind(LoggerFactory.java:121) 
 at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:112) 
 at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:275) 
 at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:248) 
 at com.unmi.TestJCLOverSlf4j.<clinit>(TestJCLOverSlf4j.java:10) 
Caused by: java.lang.IllegalStateException: Detected both jcl-over-slf4j.jar AND slf4j-jcl.jar on the class path, preempting StackOverflowError. See also http://www./codes.html#jclDelegationLoop for more details. 
 at org.slf4j.impl.JCLLoggerFactory.<clinit>(JCLLoggerFactory.java:64) 
 ... 8 more 
Exception in thread "main" 

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多