# Log
- 首先定义一个基类
org.apache.ibatis.logging.Log
public interface Log { boolean isDebugEnabled(); boolean isTraceEnabled(); void error(String s, Throwable e); void error(String s); void debug(String s); void trace(String s); void warn(String s); }
# LogImpl
- 使用不同的供应商分别实现这个接口
例如slf4j的实现: org.apache.ibatis.logging.slf4j.Slf4jImpl
且在每个实现类创建有参的构造方法,用于传递logName
# LogFactory
- 首先在静态代码块中有序尝试实现支持的日志系统
- 尝试实现,失败了就捕获异常,继续尝试下一个
private static void tryImplementation(Runnable runnable) { if (logConstructor == null) { try { runnable.run(); } catch (Throwable t) { // ignore } } }
- 实现逻辑,获取到有参的构造方法,并赋值给类变量
private static Constructor<? extends Log> logConstructor;
private static void setImplementation(Class<? extends Log> implClass) { try { Constructor<? extends Log> candidate = implClass.getConstructor(String.class); 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); } }
- 既然已经获取到了
Log
的构造方法,那么在LogFactory.getLog(x)获取Log的时候,通过这个构造方式实例化对象,即可获取到Log
public static Log getLog(Class<?> aClass) { return getLog(aClass.getName()); } public static Log getLog(String logger) { try { return logConstructor.newInstance(logger); } catch (Throwable t) { throw new LogException("Error creating logger for logger " + logger + ". Cause: " + t, t); } }
# 其他
- 在mybatis源码中,三方的日志依赖都是
<optional>true</optional>
的,不传递日志的依赖,由用户来选择使用的日志供应商。