mybatis 源码分析
日志模块
需求:
1、MyBatis 没有提供日志的实现类,需要接入第三方的日志组件,但第三方日志组件都有各自的 Log 级别,且各不相同,而 MyBatis 统一提供了 trace、debug、warn、error 四个级别;
2、自动扫描日志实现,并且第三方日志插件加载优先级如下:slf4J → commonsLoging →Log4J2 → Log4J → JdkLog;
3、日志的使用要优雅的嵌入到主体功能中;(动态代理)
整体架构设计:
具体实现:
适配器模式,解决了mybatis对其他日志框架的改造与集成。主要是mybatis定义自己的一套API接口,然后再实现的时候,将其他日志的实现嵌入到mybatis的APi接口中,以Slf4j为例,如下图所示:
其中 Slf4jLocationAwareLoggerImpl Slf4jLoggerImpl 都是为了提供统一的API接口而存在的
代理模式(动态代理),主要解决日志打印问题,如何在mybatis获得日志对象之后,针对每一步数据库操作进行打印日志。
首先搞清楚那些地方需要打印日志?通过对日志的观察,如下几个位置需要打日志:
1、在创建 prepareStatement 时,打印执行的 SQL 语句;
2、访问数据库时,打印参数的类型和值
3、查询出结构后,打印结果数据条数
因此在日志模块中有 BaseJdbcLogger 、 ConnectionLogger 、 PreparedStatementLogger 和 ResultSetLogge 通过动态代理负责在不同的位置打印日志;几个相关类的类图如下: