Mybatis源码学习——logging
Mybatis源码地址:https://github.com/mybatis/mybatis-3
有中文注释源码地址:https://github.com/tuguangquan/mybatis
mybatis下的包
- logging -日志-对象适配器设计模式
- exceptions-异常
- cache-缓存
- parsing-xml解析,${} 格式的字符串解析
- type-类型处理器
- IO-通过类加载器在jar包中寻找一个package下满足条件(比如某个接口的子类)的所有类
- reflection-反射
- datasource-数据源
- transaction-事务
- session-会话
- jdbc-jdbc单元测试工具
- builder-构建
- mapping-映射
- scripting-脚本
- annotations-注解
- binding-绑定
- executor-执行器
- plugin-插件
1.logging
MyBatis 内置日志工厂基于运行时自省机制选择合适的日志工具。它会使用第一个查找得到的工具(按上文列举的顺序查找)。如果一个都未找到,日志功能就会被禁用。
在userSlf4jLogging()方法中会调用setImplementation方法传入Slf4J的全路径名,至此得到了SLF4J的构造方法
在Slf4jImpl实现类中通过代理模式,在调用方法时完成具体实现
//代理模式,委派给Slf4jLoggerImpl或者Slf4jLocationAwareLoggerImpl,所以这个类只是一个wrapper
private Log log;
//构造方法
public Slf4jImpl(String clazz) {
Logger logger = LoggerFactory.getLogger(clazz);
if (logger instanceof LocationAwareLogger) {
try {
//在Slf4jImpl构造方法中通过反射拿到Logger中的方法,这个方法是Log4jLoggerAdapter中的log方法
// check for slf4j >= 1.6 method signature 只为为了检查版本是否符合
logger.getClass().getMethod("log", Marker.class, String.class, int.class, String.class, Object[].class, Throwable.class);
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
log = new Slf4jLoggerImpl(logger);
}
在LogFactory日志工厂中会根据static代码块中的顺序找到第一个所查找到的工具,如果一个未找到则会是no logging禁用日志,同时也可以根据以下方法指定日志
org.apache.ibatis.logging.LogFactory.useSlf4jLogging();
org.apache.ibatis.logging.LogFactory.useLog4JLogging();
org.apache.ibatis.logging.LogFactory.useJdkLogging();
org.apache.ibatis.logging.LogFactory.useCommonsLogging();
org.apache.ibatis.logging.LogFactory.useStdOutLogging();
//同时LogFactory提供一个扩展功能,如果以上log都不满意,可以使用自定义的log
public static synchronized void useCustomLogging(Class<? extends Log> clazz) {
setImplementation(clazz);
}
亦可以mybatis-config.xml在中指定日志工具
<configuration>
<settings>
...
<setting name="logImpl" value="LOG4J"/>
...
</settings>
</configuration>
logImpl 可选的值有:SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING,或者是实现了接口 org.apache.ibatis.logging.Log 的,且构造方法是以字符串为参数的类的完全限定名。(可以参考org.apache.ibatis.logging.slf4j.Slf4jImpl.java的实现)