前言
MyBatis自定义了一套日志体系,这个体系的目的是灵活的使用主流的日志框架,如log4j、log4j2、slf4j等等。
image.png
实现机制
-
自定义日志接口
image.png -
适配器模式适配各个主流日志框架
image.png -
日志工厂类
日志工厂中通过静态方式尝试加载各种常用的日志框架,按顺序只要有一个加载成功,就使用加载成功的那个日志框架。
lambda表达式实现runnable接口
这里看一下tryImplementation,这里调用的不是start,而是run!
private static void tryImplementation(Runnable runnable) {
if (logConstructor == null) {
try {
//这里调用的不是start,而是run!根本就没用多线程嘛!
runnable.run();
} catch (Throwable t) {
// ignore
}
}
}
而这个 runnable.run()执行的下图方法中某一个
image.png
而方法setImplementation的代码,就是尝试实例化指定的框架适配器,如果实例化不成功则抛出异常,如果实例化成功则说明找到了具体的日志框架实现。如下:
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,一旦设上,表明找到相应的log的jar包了,那后面别的log就不找了。
logConstructor = candidate;
} catch (Throwable t) {
throw new LogException("Error setting Log implementation. Cause: " + t, t);
}
}
小技巧
MyBatis在编译阶段是需要依赖所有的日志框架的,所以pom文件中列出了主流的日志框架,但实际在运行阶段是需要使用者去指定其中某一个日志框架的,在这里MyBatis使用了maven的可选依赖功能,即<optional>true</optional>
网友评论