您所在的位置:主页 > JAVA技术 >

spring之logging

时间:2018-06-04 10:18来源:未知 作者:os 点击:

 

 

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