一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

SLF4J 的幾種實際應用模式--之三:JCL-Over-SLF4J+SLF4J

 CevenCheng 2010-09-08

SLF4J 的幾種實際應用模式--之三:JCL-Over-SLF4J+SLF4J

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

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

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

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

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

 需要的配置文件和組件包,下面四個 jar 文件和一個 xml文件都是要放在項目的 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 個包在 http://www./download.html 處下載,第二第三個包在 http://logback./download.html 下載,可能包文件名中的版本號有些差異。 

下面是一個最簡單的 logback.xml 文件內容 

 <?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],來檢驗是否統一到單一的日志通道中去了。 

使用 了 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 輸出日志,從輸出可以看到它們統一到一個通道中了

public static void main(String[] args) {

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

log.info("Hello From JCL");

}

}

 

我們在上面代碼中,既使用了 JCL 統一日志框架,也使用了 SLF4J 的統一日志框架。要注意一點,從 JCL 橋接過來的 log 不能輸出參數化消息了。上面代碼使用了 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 框架的日志輸出都統一到了一個通道中來了,為什么呢? SLF4J 使用的是 Logback 輸出的信息,這一點沒問題的,而 JCL 是不認識 Logback 的,所以 JCL 框架的輸出必然是繞道到 SLF4J,最后也是由 Logback 輸出的。 

實現分析: 

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

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

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

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

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 運行時使用了 SLF4JLogFactory,從而完成了 JCL 的日志實現委托給了 SLF4J,再由 SLF4J 進一步完成具體的日志輸出。 

采用 JCL-Over-SLF4J+ SLF4J+Log4J 使用模式也是相似的,這里就不詳述了。總結下就是 JCL 把 SLF4J 當作它的日志實現。 

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

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" 

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    暴力三级a特黄在线观看| 国产精品午夜性色视频| 日韩欧美综合中文字幕 | 91精品日本在线视频| 久久亚洲精品成人国产| 成人免费视频免费观看| 91偷拍裸体一区二区三区| 成在线人免费视频一区二区| 欧美欧美日韩综合一区| 扒开腿狂躁女人爽出白浆av| 99久久国产综合精品二区| 国产对白老熟女正在播放| 91蜜臀精品一区二区三区| 国产成人精品一区二区在线看| 国产精品白丝久久av| 九九热这里只有精品哦| 又黄又色又爽又免费的视频| 国产亚洲视频香蕉一区| 极品少妇嫩草视频在线观看| 国产又黄又爽又粗视频在线| 欧美大胆女人的大胆人体| 亚洲av成人一区二区三区在线| 日本乱论一区二区三区| 免费特黄欧美亚洲黄片| 亚洲国产精品肉丝袜久久| 东北老熟妇全程露脸被内射| 爽到高潮嗷嗷叫之在现观看| 亚洲午夜av一区二区| 中文字幕日韩精品人一妻| 欧美日韩国产精品第五页| 日韩一区二区三区18| 亚洲伦片免费偷拍一区| 亚洲一区二区三区三州| 午夜精品久久久免费视频| 国产自拍欧美日韩在线观看| 国产精品免费福利在线| 日韩熟妇人妻一区二区三区| 日韩午夜福利高清在线观看| 日本乱论一区二区三区| 国产av精品高清一区二区三区| 国产一级性生活录像片|