查看源码的建议:
1、源代码的类虽然很多,但是一般是有一个清晰的结构的(当然有些项目确实结构混乱,东一撮西一撮的,那没关系,不读就是了)。所以在深入到具体的细节之前,应该先把整个代码的结构梳理清楚,再一块一块地往下读。梳理清楚了脉络和结构,可以直接跳过不想深究的细节,只要知道它是干什么的就行了,当用到的时候再来看
2、源代码的类虽然很多,但是一般会有一个入口。比如hibernate的SessionFactory,spring的ApplicationContext,logback的LoggerFactory。从入口进去,一点点地读,必要的时候使用debug功能跟着走一走,相信会清晰很多
以前我就是进了误区,哎
slf4j最关键的是2个接口,和一个入口类。搞清楚了这3个,对slf4j就会比较清楚了。
最关键的2个接口,分别是Logger和ILoggerFactory。
最关键的入口类,是LoggerFactory
所有的具体实现框架,一定会实现Logger接口和ILoggerFactory接口。前者实际记录日志,后者用来提供Logger,重要性不言自明。而LoggerFactory类,则是前面说过的入口类。
private final static Logger LOGGER = LoggerFactory.getLogger(RequestController.class);
不管实现框架是什么,要获取Logger对象,都是通过这个类的getLogger()方法,所以这个类也非常重要。具体实现框架和slf4j的对接,就是通过这个类
如图,每个日志框架都需要实现ILoggerFactory接口,来说明自己是怎么提供Logger的。像log4j、logback能够提供父子层级关系的Logger,就是在ILoggerFactory的实现类里实现的。同时,它们也需要实现Logger接口,以完成记录日志。为啥log4j和logback可以一个Logger对应多个Appender?这就要去分析它们的Logger实现类。
slf4j自带的NOPLoggerFactory,实现了ILoggerFactory,其getLogger()方法很简单,就是返回一个NOPLogger
public class NOPLoggerFactory implements ILoggerFactory { public NOPLoggerFactory() { // nothing to do } public Logger getLogger(String name) { return NOPLogger.NOP_LOGGER; } }
NOPLogger实现了Logger接口,它就更简单,如同它的名字一样:什么都不做
public class NOPLogger extends MarkerIgnoringBase { private static final long serialVersionUID = -517220405410904473L; /** * The unique instance of NOPLogger. */ public static final NOPLogger NOP_LOGGER = new NOPLogger(); /** * There is no point in creating multiple instances of NOPLogger, * except by derived classes, hence the protected access for the constructor. */ protected NOPLogger() { } /** * Always returns the string value "NOP". */ public String getName() { return "NOP"; } /** * Always returns false. * @return always false */ final public boolean isTraceEnabled() { return false; } /** A NOP implementation. */ final public void trace(String msg) { // NOP } /** A NOP implementation. */ final public void trace(String format, Object arg) { // NOP } /** A NOP implementation. */ public final void trace(String format, Object arg1, Object arg2) { // NOP } /** A NOP implementation. */ public final void trace(String format, Object... argArray) { // NOP } /** A NOP implementation. */ final public void trace(String msg, Throwable t) { // NOP } /** * Always returns false. * @return always false */ final public boolean isDebugEnabled() { return false; } /** A NOP implementation. */ final public void debug(String msg) { // NOP } /** A NOP implementation. */ final public void debug(String format, Object arg) { // NOP } /** A NOP implementation. */ public final void debug(String format, Object arg1, Object arg2) { // NOP } /** A NOP implementation. */ public final void debug(String format, Object... argArray) { // NOP } /** A NOP implementation. */ final public void debug(String msg, Throwable t) { // NOP } /** * Always returns false. * @return always false */ final public boolean isInfoEnabled() { // NOP return false; } /** A NOP implementation. */ final public void info(String msg) { // NOP } /** A NOP implementation. */ final public void info(String format, Object arg1) { // NOP } /** A NOP implementation. */ final public void info(String format, Object arg1, Object arg2) { // NOP } /** A NOP implementation. */ public final void info(String format, Object... argArray) { // NOP } /** A NOP implementation. */ final public void info(String msg, Throwable t) { // NOP } /** * Always returns false. * @return always false */ final public boolean isWarnEnabled() { return false; } /** A NOP implementation. */ final public void warn(String msg) { // NOP } /** A NOP implementation. */ final public void warn(String format, Object arg1) { // NOP } /** A NOP implementation. */ final public void warn(String format, Object arg1, Object arg2) { // NOP } /** A NOP implementation. */ public final void warn(String format, Object... argArray) { // NOP } /** A NOP implementation. */ final public void warn(String msg, Throwable t) { // NOP } /** A NOP implementation. */ final public boolean isErrorEnabled() { return false; } /** A NOP implementation. */ final public void error(String msg) { // NOP } /** A NOP implementation. */ final public void error(String format, Object arg1) { // NOP } /** A NOP implementation. */ final public void error(String format, Object arg1, Object arg2) { // NOP } /** A NOP implementation. */ public final void error(String format, Object... argArray) { // NOP } /** A NOP implementation. */ final public void error(String msg, Throwable t) { // NOP } }