写给大忙人看的,MyBatis日志如何做到兼容常用的日志框架

前言日志 , 在我们开发中是一个非常重要的话题 , 良好的日志打印可以帮助我们快速的定位问题 , 可能现在我们开发用到最多的日志框架就是slf4j了 , 但是日志还有其他很多优秀的框架 , 比如:Apache Common Log , Log4j , java.util.logging等 。 MyBatis作为一款优秀的ORM框架 , 定义了一套统一的日志接口供应用层调用 , 而底层却利用适配器模式兼容了我们上面所列出来的常用日志框架 。
MyBatis日志分类在介绍MyBatis的全局配置文件的时候 , 我们提到setting内有一个属性logImpl , 可以配置的选项有:SLF4J , LOG4J , LOG4J2 , JDK_LOGGING , COMMONS_LOGGING , STDOUT_LOGGING , NO_LOGGING 。 这就说明MyBatis支持六种日志类型(NO_LOGGING是不打印日志) 。 我们看一下MyBatis的日志模块也可以很明显的看出六种日志类型:
写给大忙人看的,MyBatis日志如何做到兼容常用的日志框架文章插图
它们的对应关系为:
写给大忙人看的,MyBatis日志如何做到兼容常用的日志框架文章插图
PS:需要注意的是 , SLF4J并不是一个具体的日志框架 , 也就是我们不能单独只配置SLF4J而不引入其他任何具体的日志框架 。
简单谈谈SLF4JSLF4J:简单日记门面 。 (英文全称为simple logging Facade for Java) , 这个是用来为各种日志框架提供一个简单的统一的接口 , 这样使得我们在切换日志框架的时候可以直接替换jar包就可以了 , 而无需修改源代码 。
logback我想大家都用过 , logback是一个实现了具体日志打印的框架 , 但是MyBatis上面列出来的分类并没有支持logback , 它又为什么能够打印呢?这就是SLF4J的作用了 , 因为logback也实现了SLF4J提供的接口 , 所以我们需要将logback和SLF4J结合配置使用才行 。 而后面的介绍中也可以看到 , MyBatis中如果我们不指定日志种类的时候 , 优先选择的就是SLF4J , 这正是因为SLF4J可以和其他许多日志框架一起结合来使用 。
那么假如我们指定了日志类型为SLF4J , 但是不引入其他任何实现呢?答案就是MyBatis不会打印任何日志出来 , 下图就是只配置了SLF4J而没有引入其他任何实现的警告信息:
写给大忙人看的,MyBatis日志如何做到兼容常用的日志框架文章插图
【写给大忙人看的,MyBatis日志如何做到兼容常用的日志框架】可以看到这里提示我们SLF4J没有任何实现 , 而后面的sql语句和参数这些信息也没有打印出来 。
MyBatis日志实现原理日志的解析老规矩 , 我们还是先找到加载mybatis-config配置文件中的解析日志的源码:
写给大忙人看的,MyBatis日志如何做到兼容常用的日志框架文章插图
写给大忙人看的,MyBatis日志如何做到兼容常用的日志框架文章插图
这里首先会根据我们配置的属性作为别名去TypeAliasRegistry类中查找对应的类 , 如果不存在这个别名 , 那就会把我们配置的属性直接通过Class.forName去查找日志类 , 所以看到这里就明白我们可以自定义日志类 , 只要实现Log接口就行 , 然后配置我们自己的类名就行了 。 虽然别名都存在TypeAliasRegistry类里面 , 但是我们前面介绍MyBatis配置文件的时候 , 列出了TypeAliasRegistry类中默认初始化的别名 , 并没有看到日志相关类的别名 , 那么日志的别名又是在哪里配置的呢?我们打开Configuration类:
写给大忙人看的,MyBatis日志如何做到兼容常用的日志框架文章插图
可以看到Configuration的构造方法里面也初始化了一些别名注册到TypeAliasRegistry类了 。 接下来我们看看读取到日志类之后调用了setLogImpl做了什么事情: