关于SLF4J

Spring的功能越来越强大,同时也越来越臃肿。比如想快速搭建一个基于Spring的项目,解决依赖问题非常耗时。Spring的项目模板的出现就解决了这个问题,通过这个描述文件,可以快速的找到你所需要的模板。

第一次认识SLF4J就是在这些项目模板里,它的全称是Simple Logging Facade for Java。从字面上可以看出它只是一个Facade,不提供具体的日志解决方案,只服务于各个日志系统。简单说有了它,我们就可以随意的更换日志系统(如java.util.logging、logback、log4j)。比如在开发的时候使用logback,部署的时候可以切换到log4j;如果关闭所有的log,切换到NOP就可以了。只需要更改依赖,提供日志配置文件,免去了修改代码的麻烦。

首先看如何使用:

[java] import org.slf4j.Logger; import org.slf4j.LoggerFactory;

public class HelloWorld { public static void main(String[] args) { Logger logger = LoggerFactory.getLogger(HelloWorld.class); logger.info("Hello World"); } } [/java]

SLF4J封装了使用起来和其他日志系统一样简单。上面提到过SLF4J不提供具体的日志解决方案,所以使用的时候除了要引用SLF4J包,还要引用具体的日志解决方案包(log4j、logging–JDK提供、logback),还有所对应的binding包(_slf4j-log4j__、slf4j-jdk14、logback-classic_)。

以log4j为例,我们看SLF4J的实现方式。

SLF4J类在初始化的时候会尝试从ClassLoader中org/slf4j/impl/StaticLoggerBinder.class。这个类比较特殊,每个binding包里都有。不同binding包里的StaticLoggerBinder类会去初始化一个相应的实例,如slf4j-log4j里:

[java] /** * 截取的部分代码 */ private StaticLoggerBinder() { loggerFactory = new Log4jLoggerFactory(); } [/java]

而Log4jLoggerAdapter实现了SLF4J的Logger接口,使用了Adapter模式对Log4j的Logger进行了封装并暴露了Logger的接口,Log4jLoggerFactory持有了Log4jLoggerAdapter的实例。

[java] /** * 截取的部分代码 */ public class Log4jLoggerFactory implements ILoggerFactory { public Logger getLogger(String name) { Logger slf4jLogger = null; // protect against concurrent access of loggerMap synchronized (this) { slf4jLogger = (Logger) loggerMap.get(name); if (slf4jLogger == null) { org.apache.log4j.Logger log4jLogger; if(name.equalsIgnoreCase(Logger.ROOT_LOGGER_NAME)) { log4jLogger = LogManager.getRootLogger(); } else { log4jLogger = LogManager.getLogger(name); } slf4jLogger = new Log4jLoggerAdapter(log4jLogger); loggerMap.put(name, slf4jLogger); } } return slf4jLogger; } } [/java]

具体的Log解决方案就不做剖析了。

Comments

comments powered by Disqus