What?
The Simple Logging Facade for Java (SLF4J)
作为其他主流日志框架(如. java.util.logging, logback, log4j)的Facade
,为用户灵活、即插即用的切换其他日志提供统一的接口。
什么Facade: http://blog.csdn.net/lemon89/article/details/46846249
How to Use
在无需适配其他日志框架时,引入
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(LoggerTest.class.getName());
logger.info("now {}", logger.getClass());
logger.debug("Temperature set to {}. Old temperature was {}.", 123, 234234);
}
此时运行后并没有日志打印出来,warning信息:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
这是因为sl4j作为一个Facade,并没有提供实现,默认绑定到slf4j-nop-1.7.21.jar,nop 不做任何日志记录:
public NOPLoggerFactory() {
// nothing to do
}
如果需要留下日志,则slf4j需要在编译时加载并通过org.slf4j.impl.StaticLoggerBinder绑定到一个具体的日志框架。
此时通过引入log4j或其他日志框架,使得slf4j在运行时可以在classpath中加载到具体的绑定(slf4j bindings )。
当然,如果你确定不需要日志,可以手动加入引入slf4j-nop依赖,屏蔽warning信息,sl4j-nop也是一个实现jar,只是什么日志都不做。
另外说一下logback-classic-*.jar,logback本身就是基于slf4j接口编写的,并且同时实现了日志记录功能,并不需要通过slf4绑定。如需要使用,直接引入这个jar即可。
静态绑定
SLF4J binding is hardwired at compile time
slf4j会在编译时绑定具体的日志实现模块,这里的绑定并没有使用任何classloader,因此避免了同类产品容易出现的 class loader问题、内存溢出问题。
官网的这种图清晰的描述了slf4j与slf4j bindings的适配使用,对于application层,具体的日志框架对我们都是透明的,我们只针对slf4j-api编程。
这句话描述了slf4j的亮点:
No knowledge of class loaders is necessary as SLF4J does not make use
nor does it directly access any class loaders. As a consequence, SLF4J
suffers from none of the class loader problems or memory leaks
observed with Jakarta Commons Logging (JCL).
注意:如果我们构建 libraries jar 或者 frameworks,此时不应该引入任何具体的日志框架,应该把这个binding决定权交给终端用户。有时为了完成testcase,可以引入一个过度依赖,比如:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>test</scope>
</dependency>
slf4j静态绑定原理
SLF4J 会在编译时会绑定import org.slf4j.impl.StaticLoggerBinder; 该类里面实现对具体日志方案的绑定接入。任何一种基于slf4j 的实现都要有一个这个类。如:org.slf4j.slf4j-log4j12-1.5.6: 提供对 log4j 的一种适配实现。注意:如果有任意两个实现slf4j 的包同时出现,那么就可能出现问题。
注意:使用参数化方式打印日志以提升性能
http://www.slf4j.org/faq.html#logging_performance