注:本文源码版本为3.4.6
日志模块总览
Log:是日志接口。
LogException:定义异常类。
LogFactory:日志工厂类,他的作用是用来判断使用哪个日志框架。
commons包:整合jcl框架。
jdk14包:整合jul框架。
log4j包:整合log4j框架。
log4j2包:整合log4j2框架。
nologging包:不整合日志。
slf4j包:整合slf4j框架。
stdout包:控制台输出日志。
jdbc包:记录JDBC语句日志。
框架整合
这些包里面的类,大部分都实现了Log接口。
NoLoggingImpl:实现方法里面什么都没做。
StdOutImpl:实现方法里面使用System.err.println(s);来输出日志。
Log4jImpl:实现方法里使用了org.apache.log4j.Logger类的log.log(FQCN, Level.ERROR, s, null);等输出日志。
Jdk14LoggingImpl:实现方法里使用java.util.logging.Logger类的log.log(Level.SEVERE, s);等来输出日志。
JakartaCommonsLoggingImpl:实现方法里使用了org.apache.commons.logging.Log类的log.debug(s);等方法来输出日志。
Log4j2LoggerImpl:实现方法里使用了org.apache.logging.log4j.Logger类的log.debug(MARKER, s);等方法来输出日志。
Log4j2AbstractLoggerImpl:实现方法里使用org.apache.logging.log4j.spi.ExtendedLoggerWrapper类的log.logIfEnabled(FQCN, Level.DEBUG, MARKER, new SimpleMessage(s), null);等方法来输出日志。
Log4j2Impl:是Log4j2AbstractLoggerImpl和Log4j2LoggerImpl的封装,可以通过传入类名来判断使用哪个类。
Slf4jLoggerImpl:实现方法里使用了org.slf4j.Logger类的log.debug(s);等方法来输出日志。
Slf4jLocationAwareLoggerImpl:实现方法里使用了org.slf4j.spi.LocationAwareLogger类的logger.log(MARKER, FQCN, LocationAwareLogger.TRACE_INT, s, null, null);等方法来输出日志。
Slf4jImpl:是Slf4jLoggerImpl和Slf4jLocationAwareLoggerImpl的整合,通过传入的类名来判断使用哪个类。
public Slf4jImpl(String clazz) {
//根据类名获取Logger对象
Logger logger = LoggerFactory.getLogger(clazz);
//如果Logger是LocationAwareLogger接口的实现类
if (logger instanceof LocationAwareLogger) {
try {
// check for slf4j >= 1.6 method signature
//检查slf4j版本是否大于等于1.6
logger.getClass().getMethod("log", Marker.class, String.class, int.class, String.class, Object[].class, Throwable.class);
//满足要求就返回Slf4jLocationAwareLoggerImpl
log = new Slf4jLocationAwareLoggerImpl((LocationAwareLogger) logger);
return; } catch (SecurityException e) {
// fail-back to Slf4jLoggerImpl
} catch (NoSuchMethodException e) {
// fail-back to Slf4jLoggerImpl
}
}
// Logger is not LocationAwareLogger or slf4j version < 1.6
//如果版本小于1.6或者不是LocationAwareLogger的实现类,那么使用Slf4jLoggerImpl
log = new Slf4jLoggerImpl(logger);
}
LogFactory类
定义了MARKER为MYBATIS,有些日志框架需要使用该参数,如slf4j、log4j2。
getLog(Class<?> aClass)与getLog(String logger) 用来获取Log对象。
使用方式:
Log log = LogFactory.getLog(DefaultVFS.class);
在LogFactory里面,首先会通过线程尝试每个日志框架,只要找到其中一个,就会把值赋值给logConstructor,找到之后就不再继续查找。
LogFactory类中提供了很多useXXX的方法,表示使用哪个框架。最核心的方法是:
private static void setImplementation(Class<? extends Log> implClass) {
try {
//生成字符串类型的构造器
Constructor<? extends Log> candidate = implClass.getConstructor(String.class);
//获取Log对象,输出一下日志
Log log = candidate.newInstance(LogFactory.class.getName());
if (log.isDebugEnabled()) {
log.debug("Logging initialized using '" + implClass + "' adapter.");
}
//赋值
logConstructor = candidate;
} catch (Throwable t) {
throw new LogException("Error setting Log implementation. Cause: " + t, t);
}
}
该方法就是用来获取具体使用哪个日志框架。
jdbc日志
当把mybatis设置了debug,那么会输出mybatis的一些执行语句。
如,只有debug的时候才会输出日志。
注意:本文归作者所有,未经作者允许,不得转载