SLF4J的全称是Simple Logging Facade 4 Java,从名称即可看出,这是一个针对Java的logging的一个简单的门面。
提到门面(Facade),我们就要谈论到Facade Pattern,提到Facade Pattern我们可以去参见这篇文章:设计模式(15)-Facade Pattern 设计模式(15)-Facade Pattern。
那么这里SLF4J由于使用了门面模式,所以我们可以在代码中通过使用SLF4J的接口编写代码,等到实际运行的时候通过配置我们使用的实际的类库,来选择我们在运行时使用来进行logging的framework。也就是说:我们在运行时,如果发现使用的java自带的java.util.logging.Logger用得不开心而期望使用Log4J,那么很简单,只要我们将Log4J的jar包引入classpath,然后添加SLF4J对应的connector即可。是不是很方便?那么我们接着开始。
提到SLF4J就不能不提到大名鼎鼎的JCL:Jakarta Commons Logging (JCL)提供的是一个日志(Log)接口(interface),同时兼顾轻量级和不依赖于具体的日志实现工具。它提供给中间件/日志工具开发者一个简单的日志操作抽象,允许程序开发人员使用不同的具体日志实现工具。
了解JCL包里情况,可以查看它的API文档:http://www.oschina.net/uploads/doc/commons-logging-1.1.1/index.html , 其中Log(基本记录器)和LogFactory(负责创建Log实例)是两个基类。该API直接提供对下列底层日志记录工具的支持:Jdk14Logger,Log4JLogger,LogKitLogger,NoOpLogger (直接丢弃所有日志信息),还有一个SimpleLog。
有必要详细说明一下调用LogFactory.getLog()时发生的事情。调用该函数会启动一个发现过程,即找出必需的底层日志记录功能的实现,具体的发现过程在下面列出: ( 换句话说就是, 有这么多工具,common-logging该使用哪一个呢?这取决于系统的设置,common-logging将按以下顺序决定使用哪个日志记录工具:
但从上面可以很清楚的看出,JCL绑定Log4J是非常紧的。尽管Log4J目前是最好用的logging工具,但1.x版本已经基本很少在维护了,而2.x版本迟迟未能release。所以,我们需要更灵活的选择——SLF4J。
我们同样使用Maven建立我们的project。在pom.xml中我们指定我们需要的logger的dependency,这里我们特意选定了一个特殊的Logger:logback。
<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.0.13</version> </dependency>注意logback依赖了SLF4J,所以我们的工程得以编译通过,然后我们在运行时检查发现通过maven依赖我们的工程中包含了logback的连接器,所以输出的时候使用logback输出。
public class AppTest { private static final Logger logger = LoggerFactory.getLogger(AppTest.class); @Test public void testSLF4J() { logger.debug("debug infor {}", AppTest.class); } }
如果需要使用Log4J,我们将dependency修改为:
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.7</version> </dependency>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'> <appender name="myConsoleAppender" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="[%d{yy-MM-dd HH:mm:ss,SSS\} %-5p] [%t] %c %n -%l - %m%n" /> </layout> </appender> <!-- 根logger的设置 --> <root> <!-- root级别输出设置 --> <priority value="debug" /> <!-- 目的地 --> <appender-ref ref="myConsoleAppender" /> </root> </log4j:configuration>