1. 程式人生 > >Spring(一)Spring中的logging實現

Spring(一)Spring中的logging實現

sprign中的logging實現簡介

  對於spring架構,Jakarta Commons Logging API (JCL)是強制依賴的。spring將JCL反編譯,並使得它們對類可見,從而擴充套件spring。程式設計師應該要意識到,所有版本的spring使用同一個logging庫:因此遷移是很容易的,因為保證了向下相容。程式設計師其實需要做的只是設定spring的某些模組,使其明確地依賴到commons-logging(一個權威的JCL實現包)上,同時使其他模組也在編譯時依賴它。另外,spring-core模組就是依賴commons-logging的。

  commons-logging的最大好處是你無需做任何動作,就能讓你的WEB應用得以使用它。因為它有一個實時檢索演算法,能直接在classpath上發現logging架構,然後使用一個它認為合適的(你也可以指定一個)。JDK(java.util.logging or JUL for short)和它沒比。

然而並不建議使用Commons Logging

  遺憾的是,commons-logging的實時檢索演算法是有問題的——如果我們復位時鐘,同時作為一個新專案啟動spring的話,它會更換使用一個新的logging依賴,這就是問題所在。因此在這裡,我們推薦使用Simple Logging Facade for Java( SLF4J)。

  在使用SLF4J之前,先考慮關掉commons-logging,下面有兩種方法:

  1. 排除spring-core模組對它的依賴(因為它是唯一一個明確依賴commons-logging的模組)
  2. 依賴一個特殊的commons-logging包,它的特殊性在於這個包是空的,其實就是用一個空的名為commons-logging的包來騙spring

  1.的實現方法如下maven配置即可:

<dependencies>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.2.4.RELEASE</version>//這個根據情況定義版本
    <exclusions>
      <exclusion>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
  </dependency>
</dependencies>

 
   

  雖然在這裡,我們已經關掉關掉commons-logging,但僅僅這樣的話,WEB應用會崩潰掉,因為在classpath上已經沒有JCL API的任何實現了,因此要有一個新的來填補,這時候SLF4J就是一個很好的選擇。

使用SLF4J

  相比common-logging,SLF4J是一個更乾淨的依賴,而且更高效的選擇,因為它使用的是編譯時繫結,而不是實時檢索繫結。也因為如此,你需要一開始就確定好你要編譯的logging實現。SLF4J能夠繫結許多通用的Logging框架,因此程式設計師可以自行選擇並進行配置即可使用。

  SLF4J也可以繫結JCL,它做了相反的動作:使它和其他logging框架橋接。因此你如果要在spring使用SLF4J,你需要用SLF4J-JCL bridge替代commons-logging。一旦這樣做,spring的log呼叫都會被翻譯成呼叫SLF4J API,因此如果你的WEB應用使用這個API,你會有一個單獨的地方專門去配置和管理它。

  一個常見logging方案,就是先實現spring與SLF4J橋接的方案,然後再實現SLF4J繫結LOG4J。你需要提供4個依賴(當然需要exclude掉commons-logging):the bridge, the SLF4J API, the binding to Log4J, and the Log4J implementation itself。見如下maven配置:

<dependencies>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.2.4.RELEASE</version>
    <exclusions>
      <exclusion>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
    <version>1.5.8</version>
  </dependency>
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.5.8</version>
  </dependency>
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.5.8</version>
  </dependency>
  <dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.14</version>
  </dependency>
</dependencies>

 
   

  看上去要很多依賴,挺麻煩,你也可以不這個方案,但它的確要比commons-logging要好,尤其是在一些很嚴格的容器如OSGi。而且據說,因為編譯時繫結,效能會更加好。

  SLF4J其實還有一個更常見的實現方案,可以減少繁瑣依賴包,那就是直接繫結Logback。這種方式可以跳過額外繁瑣的繫結步驟,因為Logback直接實現了SLF4J,因此你只需要依賴兩個包(jcl-over-slf4j 和logback)而不是4個。如果你這樣做,你可能還需要排除掉其他模組對slf4j-api包的依賴,因為你不能讓多個版本的slf4j-api共存(因為Logback已經包含)。

使用LOG4J

  很多程式設計師都使用log4j作為logging框架,因為它可以配置從而達到管理目的。它很高效,成熟,實際上也是spring在runtime時使用以及測試的包。spring提供了一些工具去配置和初始化log4j,因此某些模組可以選擇編譯時依賴它。

  預設情況下,通過JCL(commons-logging)搭配log4j,你只需要做的引入log4j包,同時提供配置檔案(log4j.properties or log4j.xml)到classpath的根路徑上。maven配置如下:

<dependencies>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.2.4.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.14</version>
  </dependency>
</dependencies>

 
   

log4j.properties樣本:

log4j.rootCategory=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n
log4j.category.org.springframework.beans.factory=DEBUG