SLF4J日志系统门面模式(转载)
import org.slf4j.LoggerFactory;
publicclassHelloWorld{
publicstaticvoid main(String[] args){
Loggerlogger=LoggerFactory.getLogger(HelloWorld.class);
logger.info("HelloWorld");
}
从源码分析slf4j
从使用过程来看,slf4j的核心类很明显是Logger类,但是看了源码会发现Logger类只是一个接口。这个不难理解,因为slf4j只是一个 Facade。
浏览一遍Logger接口,会发现里面的方法有规律,根据规律可以把接口的方法分成5大类
- trace
- debug
- info
- warn
- error
从方法名可以看出来这些方法是日志的5个级别,也就是Logger类是一个提供输出不同级别日志的接口。
Logger类的初始化方式是通过LoggerFactory来创建的。从名字一看就知道这里采用了工厂设计模式。Logger可以是不同的实现,但是创建过程我们不过关心,交给工厂来操作就OK了。
通过LoggerFactory的getLogger(Class<?> clazz)方法可以创建一个Logger LoggerFactory.getLogger(xxx.class);
方法内部其实是调用了另外一个重载的方法Logger logger = getLogger(clazz.getName());
也就是使用了类的全限定名来作为参数。
getLogger(String name)方法又调用了getILoggerFactory()方法,这个方法的作用是获得一个Logger工厂。getILoggerFactory方法很关键,它调用了SLF4J bindings的StaticLoggerBinder类。比如我的项目里用了Log4j,这里StaticLoggerBinder会返回一个Log4jLoggerFactory对象。
得到了Log4jLoggerFactory就可以得到Log4j的Logger了吗?也没那么快。因为Log4jLoggerFactory是slf4j-log4j包的类。也就是说,还没有真正调用Log4j。slf4j-log4j相当于只是一个中间件,来协调Log4j和Slf4j。
我们来看看Log4jLoggerFactory的getLogger方法,方法里面调用了LogManager的getLogger方法。LogManager才是log4j的类。从名字可以看出来LogManager是用来管理Logger的类。暂时称它为log管理器吧,log管理器里面也有一个getLogger方法,这里才是真正创建Log4j的Logger的地方。调用了log管理器的getLogger后,Log4jLoggerFactory的getLogger方法就得到了一个Log4j的Logger。
Log4jLoggerFactory得到了Log4j的Logger对象之后会把Logger返回给Slf4j-api嘛?我们看源码,并不是这样。这里使用了一个适配器Log4jLoggerAdapter。看Log4jLoggerAdapter的源码会发现它也实现了Logger接口,所以Log4jLoggerFactory可以直接把适配器返回给Slf4j-api。
import org.slf4j.LoggerFactory;
publicclassHelloWorld{
publicstaticvoid main(String[] args){
Loggerlogger=LoggerFactory.getLogger(HelloWorld.class);
logger.info("HelloWorld");
}
从源码分析slf4j
从使用过程来看,slf4j的核心类很明显是Logger类,但是看了源码会发现Logger类只是一个接口。这个不难理解,因为slf4j只是一个 Facade。
浏览一遍Logger接口,会发现里面的方法有规律,根据规律可以把接口的方法分成5大类
- trace
- debug
- info
- warn
- error
从方法名可以看出来这些方法是日志的5个级别,也就是Logger类是一个提供输出不同级别日志的接口。
Logger类的初始化方式是通过LoggerFactory来创建的。从名字一看就知道这里采用了工厂设计模式。Logger可以是不同的实现,但是创建过程我们不过关心,交给工厂来操作就OK了。
通过LoggerFactory的getLogger(Class<?> clazz)方法可以创建一个Logger LoggerFactory.getLogger(xxx.class);
方法内部其实是调用了另外一个重载的方法Logger logger = getLogger(clazz.getName());
也就是使用了类的全限定名来作为参数。
getLogger(String name)方法又调用了getILoggerFactory()方法,这个方法的作用是获得一个Logger工厂。getILoggerFactory方法很关键,它调用了SLF4J bindings的StaticLoggerBinder类。比如我的项目里用了Log4j,这里StaticLoggerBinder会返回一个Log4jLoggerFactory对象。
得到了Log4jLoggerFactory就可以得到Log4j的Logger了吗?也没那么快。因为Log4jLoggerFactory是slf4j-log4j包的类。也就是说,还没有真正调用Log4j。slf4j-log4j相当于只是一个中间件,来协调Log4j和Slf4j。
我们来看看Log4jLoggerFactory的getLogger方法,方法里面调用了LogManager的getLogger方法。LogManager才是log4j的类。从名字可以看出来LogManager是用来管理Logger的类。暂时称它为log管理器吧,log管理器里面也有一个getLogger方法,这里才是真正创建Log4j的Logger的地方。调用了log管理器的getLogger后,Log4jLoggerFactory的getLogger方法就得到了一个Log4j的Logger。
Log4jLoggerFactory得到了Log4j的Logger对象之后会把Logger返回给Slf4j-api嘛?我们看源码,并不是这样。这里使用了一个适配器Log4jLoggerAdapter。看Log4jLoggerAdapter的源码会发现它也实现了Logger接口,所以Log4jLoggerFactory可以直接把适配器返回给Slf4j-api。