天天看點

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

鍘熸枃閾炬帴锛毬爃ttp://unmi.cc/jcl-over-slf4j-slf4j/聽锛屾潵鑷犻殧鍙堕粍鑾?Unmi Blog

鎴戜滑鍓嶉潰宸茬粡璁茶繃浜?SLF4J 鐨勪袱绉嶇敤娉曪細SLF4J+Log4J聽 鍜?SLF4J+Logback锛岄偅鏄湪姣旇緝鐞嗘兂鐨勬儏鍐典笅锛屾墍鐢ㄧ粍浠跺彧浣跨敤浜?SLF4J 杩欎竴绉嶇粺涓€鏃ュ織妗嗘灦鐨勬椂鍊欍€傚彲鏄?JCL聽涓€鐩村獎鍝嶆繁杩滐紝SLF4J 娓愬叆浣沖鐨勬椂涓紝鍦ㄤ綘鐨勯」鐩腑寰堝彲鑳芥墍鐢ㄧ殑缁勪歡锛屽畠浠垎鍒敤浜?JCL 鍜?SLF4J 涓ょ缁勪歡銆傛瘮濡傝鍦ㄩ」鐩腑鐢ㄤ簡 Hibernate 3.5 鍜?Struts锛屾垨鍏朵粬 Apache 鐨勪竴浜涘紑婧愮粍浠訛紝浣犲ぇ绾︿篃涓嶆兂鐢ㄤ簡 SLF4J 鐨勭粍浠舵棩蹇椾俊鎭緭鍑哄埌 A 澶勶紝鐢ㄤ簡 JCL 鐨勭粍浠舵棩蹇楄緭鍑哄埌 B 澶勶紝閭d綘鑷繁鍐欑殑浠g爜涓殑鏃ュ織淇℃伅璇ュ線鍝効鍐欏憿锛?

涓浗浜轟竴鐩撮兘鎰胯拷姹傚ぇ涓€缁燂紝涓嶅枩娆㈠煄閭﹀埗鐨勪究浜庡垎鑰屾不涔嬨€備絾璇村埌鏃ュ織杈撳嚭杩樻槸寰楃粺涓€鍒闆崟涓€閫氶亾涓潵锛屼竴鏂歸潰澶氫釜閫氶亾娴垂璧勬簮锛屽彟鏂歸潰涔熶究浜庨厤缃拰绠$悊銆傞偅涔堟棦鐒?SLF4J 鏄秼鍔匡紝褰?SLF4J 鍜?JCL 琚涪鍒頒竴涓潧瀛愰噷锛岄鍏堜細璁?SLF4J 涓轟富锛孞CL 涓鴻緟锛屼篃灏辨槸瑕佹妸 JCL 妗ユ帴鍒?SLF4J 涓婃潵锛岄€氳繃 SLF4J 缁熶竴杈撳嚭鏃ュ織淇℃伅銆備簬鏄篃灏辨槸杩欑瘒瑕佷粙缁嶇殑 SLF4J 浣跨敤妯″紡锛欽CL-Over-SLF4J+SLF4J銆?

浠庡墠闈㈠ SLF4J 鐨勮璇嗗彲鐭ワ紝鍗充嬌鎶?JCL 杞珌鍒?SLF4J锛岃繕鏄棤娉曡緭鍑烘棩蹇楋紝杩橀渶瑕佷竴绉嶆棩蹇楀疄鐜幫紝涓嬪眰璇ョ敤 Log4J 杩樺緱鐢?Log4J锛屾兂鐢?Logback聽杩樻槸瑕佺敤 Logback銆傛墍浠ュ埌浜?SLF4J 鍚庤繕寰楀線涓嬭蛋锛屼篃灏辨槸鍓嶉潰閭d袱鏉¤礬 SLF4J+Log4J 鍜?SLF4J+Logback锛屾湰绡囦嬌鐢?SLF4J 鐨勬ā寮忓叿浣撳氨瑕佸垎涓猴細

JCL-Over-SLF4J+SLF4J+Log4J聽鍜?JCL-Over-SLF4J+SLF4J+Logback锛岃繖涓ょ瀹炵幇鏂瑰紡宸笉澶氥€傚彧鏄垎鍒敤鐨?jar 鍖呭拰閰嶇疆鏂囦歡涓嶅悓锛孲LF4J+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 涓寘鍦爃ttp://www.slf4j.org/download.html聽澶勪笅杞斤紝绗簩绗笁涓寘鍦爃ttp://logback.qos.ch/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锛宨mport org.apache.commons.logging.LogFactory锛屼絾浣犲嵈鐢ㄤ笉鐫€寮曞叆 commons-logging.jar 鍖呫€?

鎵ц涓婇潰鐨勪唬鐮侊紝鐪嬪埌杈撳嚭锛? 鏈枃鍘熷閾炬帴聽http://unmi.cc/jcl-over-slf4j-slf4j/, 鏉ヨ嚜聽闅斿彾榛勮幒 Unmi Blog

[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.sun.com/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 涓嬩細鏈変粈涔堟儏鍐靛憿锛烰CL 浠g悊缁?SLF4J锛孲LF4J 鍙堢粦瀹氬埌 JCL锛屽浜嗭紝姝誨驚鐜紝StackOverFlow 閿欒锛?

SLF4J: Detected both jcl-over-slf4j.jar AND slf4j-jcl.jar on the class path, preempting StackOverflowError.

SLF4J: See also聽http://www.slf4j.org/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 alsohttp://www.slf4j.org/codes.html#jclDelegationLoop聽for more details.

at org.slf4j.impl.JCLLoggerFactory.<clinit>(JCLLoggerFactory.java:64)

... 8 more

Exception in thread "main"