1. Slf4j的使用
在上一篇随笔:的基础上配置。
(1)导入两个文件:slf4j-api-1.5.8.jar和slf4j-log4j12-1.5.8.jar。
(2)在需要日志的地方写入下面的代码:
Logger logger = LoggerFactory.getLogger(XXX.class); logger.warn("Time: {}",new Date());
第1行代码是通过工厂模式获得一个Logger,第2行代码使用Logger输出日志,{}是占位符,实现字符串的拼接。
2. Slf4j的原理
Slf4j和Commons-logging一样,并不是真正的日志实现,只是日志接口。Log4j、Logback等才是真正的日志实现。当调用Slf4j时,通过工厂模式寻找合适的实现,并返回实现。比如上面的例子,引入了Slf4j和Log4j的适配--slf4j-log4j12-1.5.8.jar,在上一篇随笔中引入了log4j-1.2.14.jar,这样,就会把Log4j作为日志的实现。
3. 为什么要使用Slf4j
有两个原因,一个是减少生成字符串的成本,另一个是使代码和日志实现独立。
比如下面的代码:
logger.debug("Result: " + getResult());
"Result: " + getResult()是作为debug()的参数,所以要先生成这个字符串,再调用debug()。如果getResult()运算量很大,耗费了很多资源才生成出来,但是定义的日志级别不包括DEBUG,这样调用getResult()就是不必要的,白白浪费了很多资源。当然,也可以先判断一下再调用:
if (logger.isDebugEnabled()) { logger.debug("Result: " + getResult()); }
但是这样代码就显得不够简洁。
Slf4j就不存在这个问题:
logger.debug("Result: {}", getResult());
占位符{}在运行时被后面的getResult()替换,所以如果日志级别不包括DEBUG,就不会调用debug(),也不会去调用getResult()了,避免了资源的浪费,也不必再去判断isDebugEnabled(),使代码更加简洁。
第二个原因是使代码和日志独立,如果在一个类库中使用Log4j,而加载这个类库的项目使用的是Logback,这样就必须把Log4j也加载进你的项目,还要进行修改和维护,带来不必要的麻烦。而如果类库使用的是Slf4j,就不存在这个问题了,不论你的项目使用的是哪一种日志实现都是可以的。