slf4j的简单介绍
SLF4J,Simple Logging Facade for JAVA,是一个十分简单的的日志facade,对于不同的日志框架做了一个封装。
对比common logging,Common logging 有一个问题就是对于不同的ClassLoader 的Invalid class loader hierarchy problem,当在OSGI这种不同Bundle不同ClassLoader中使用时,会造成很很大困难。slf4j不依赖于任何的特定的Classloader,slf4j在编译时绑定一个且仅能使用一个日志框架。原文(SLF4J does not rely on any special class loader machinery. In fact, each SLF4J binding is hardwired at compile time to use one and only one specific logging framework.)这就意味着slf4j是静态绑定的。由于slf4j是静态绑定的,所以在速度上对比common logging也有一定的优势。
下面是slf4j官方网站给出的slf4j与其他的日志框架适配的图示。
可以看到slf4j在设计上非常简单,一个slf4j的API,一个与日志框架的Adapter或者本地实现。
使用slf4j也非常简单:
private static Logger logger = LoggerFactory.getLogger(Login.class); private String getBusinessType(String xml){ String code = extractCodeFrom(xml); if(logger.isDebugEnabled()){ logger.debug("Code:{}", code); } return codeMapType(code); }
slf4j Adapter利用java的SPI 机制,对于每一个slf4j的日志的适配包,都会是一个SLF4jServiceProvider的实现类,以常用的log4j来看,从下图可以看到,slf4j-log4j12的适配包,在META-INF/services/下可以看到服务的配置文件;
配置文件表示log4j的provider类为org.slf4j.log4j12.Log4j12ServiceProvider
查找到对于的绑定时候,slf4j会检查相应的绑定是否多于一个,若多于一个,则会输出警告,不过,仅仅输出警告而已,且slf4j会随机获取一个,获取的顺序取决于适配包的加载顺序,但是这样就不能确定是不是用户想要的一个日志框架了,所以,仅添加一个日志的适配包是一个的选择。
适配的方式让更换实际的日志框架变得十分简单,仅仅需要将对于的日志框架的适配包更换便能更换整个日志的框架了。例如要将log4j替换为logback仅仅需要在maven的pom.xml中将log4j的适配包的依赖
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.5</version> </dependency>
更换为logback适配包的依赖
<dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.5</version> </dependency>
这样就可以替换掉日志框架了。
只存在一个绑定时,对每一个可适配的日志框架,slf4j会创建对应的日志工厂,比如绑定log4j时会创建Log4jLoggerFactory,Log4jLoggerFactory会实例化slf4j与log4j的适配器Log4jLoggerAdapter,Log4jLoggerAdapter实例化log4j的实例,并使用FormattingTuple将参数填充到信息中,将日志按照Log4j的layout格式输出。这样就完成了slf4j到log4j的转换了。