type
status
date
slug
summary
tags
category
icon
password
日志在我们开发过程中占据了一个非常重要的地位,是开发和运维管理之间的桥梁,在Java中的日志框架也非常多,Log4j,Log4j2,Apache Commons Log,java.util.logging,slf4j等,这些工具对外的接口也都不尽相同,为了统一这些工具,MyBatis定义了一套统一的日志接口供上层使用。首先大家对于适配器模式要了解下哦。
1、Log
Log接口中定义了四种日志级别,相比较其他的日志框架的多种日志级别显得非常的精简,但也能够满足大多数常见的使用了;
2、LogFactory
LogFactory工厂类负责创建日志组件适配器

在LogFactory类加载时会执行其静态代码块,其逻辑是按序加载并实例化对应日志组件的适配器,然后使用LogFactory.logConstructor这个静态字段,记录当前使用的第三方日志组件的适配器。具体代码如下,每个方法都比较简单就不一一赘述了。
3、 日志应用
那么在MyBatis系统启动的时候日志框架是如何选择的呢?首先我们在全局配置文件中我们可以设置对应的日志类型选择

这个"STDOUT_LOGGING"是怎么来的呢?在Configuration的构造方法中其实是设置的各个日志实现的别名的;
Configuration.java

然后在解析全局配置文件的时候就会处理日志的设置

进入方法
进入setLogImpl
再进入useCustomLogging方法
这就关联上了我们前面在LogFactory中看到的代码,启动测试方法看到的日志也和源码中的对应上来了,还有就是我们自己设置的会覆盖掉默认的sl4j日志框架的配置
4、JDBC 日志
当我们开启了 STDOUT的日志管理后,当我们执行SQL操作时我们发现在控制台中可以打印出相关的日志信息;

那这些日志信息是怎么打印出来的呢?原来在MyBatis中的日志模块中包含了一个jdbc包,它并不是将日志信息通过jdbc操作保存到数据库中,而是通过JDK动态代理的方式,将JDBC操作通过指定的日志框架打印出来。下面我们就来看看它是如何实现的。
4.1 BaseJdbcLogger
BaseJdbcLogger是一个抽象类,它是jdbc包下其他Logger的父类。继承关系如下

从图中我们也可以看到4个实现都实现了InvocationHandler接口。属性含义如下
4.2 ConnectionLogger
ConnectionLogger的作用是记录数据库连接相关的日志信息,在实现中是创建了一个Connection的代理对象,在每次Connection操作的前后我们都可以实现日志的操作。
其他几个xxxxLogger的实现和ConnectionLogger几乎是一样的就不在次赘述了,请自行观看。
4.3 应用实现
在实际处理的时候,日志模块是如何工作的,我们来看看。
在我们要执行SQL语句前需要获取Statement对象,而Statement对象是通过Connection获取的,所以我们在SimpleExecutor中就可以看到相关的代码
进入 getConnection方法中

在执行sql语句的时候
如果是查询操作,后面的ResultSet结果集操作,其他是也通过ResultSetLogger来处理的,前面的清楚了,后面的就很容易的。
- Author:atsuc
- URL:https://blog.atsuc.cn/article/blog-source-007
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!