隐藏页面特效

Mybatis源码-详解Mybatis日志设计

众所周知,Mybatis是在ORM领域,使用的较为广泛,而Mybatis日志体系,也是值得我们学习的地方,由于各个厂商都有自己的日志api,基于此,Mybatis对日志进行了封装,来适配各个厂商的日志

1. 日志级别

在Mybatis内部定义了4个级别:

  1. Error:错误
  2. warn:警告
  3. debug:调试
  4. trance:

2. 日志优先级

error>warn>debug>trance

3. 源码解析

接口

org.apache.ibatis.logging.Log

该接口定义了一系列的常用日志方法,便于日志打印

/** * 日志相关接口 * @author Clinton Begin */ public interface Log { /** * 判断debug是否打开 * @return */ boolean isDebugEnabled(); /** * 判断trance是否打开 * @return */ boolean isTraceEnabled(); /** * 错误日志打印 * @param s * @param e */ void error(String s, Throwable e); void error(String s); /** * debug日志打印 * @param s */ void debug(String s); /** * trance日志打印 * @param s */ void trace(String s); /** * warn 日志打印 * @param s */ void warn(String s); }

实现类:

基于各个厂商的日志对Log有以下实现,都基本上是根据厂商日志,编写对应的适配器类来调用对应的日志系统

日志集成核心类

org.apache.ibatis.logging.LogFactory

实现原理:

  1. 使用Static 方法在类进行初始化的时候去尝试加载对应的实现类
  2. 优先级为:slf4j>commonLog>log4j2>log4j>jdk>noLog
  3. 当获取到的实现类不为空时候则不进行加载了
/** * Copyright 2009-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.ibatis.logging; import java.lang.reflect.Constructor; /** * 日志工厂类 * @author Clinton Begin * @author Eduardo Macarron */ public final class LogFactory { /** * Marker to be used by logging implementations that support markers. */ public static final String MARKER = "MYBATIS"; /** * 日志系统构造函数 */ private static Constructor<? extends Log> logConstructor; static { //尝试加载实现类 /** * slf4j>commonLog>log4j2>log4j>jdk>noLog */ tryImplementation(LogFactory::useSlf4jLogging); tryImplementation(LogFactory::useCommonsLogging); tryImplementation(LogFactory::useLog4J2Logging); tryImplementation(LogFactory::useLog4JLogging); tryImplementation(LogFactory::useJdkLogging); tryImplementation(LogFactory::useNoLogging); } private LogFactory() { // disable construction } public static Log getLog(Class<?> clazz) { //获取日志打印 return getLog(clazz.getName()); } /** * 根据类名获取对应的日志实例 * @param logger * @return */ public static Log getLog(String logger) { try { return logConstructor.newInstance(logger); } catch (Throwable t) { throw new LogException("Error creating logger for logger " + logger + ". Cause: " + t, t); } } /** * 设置个性化日志 * @param clazz */ public static synchronized void useCustomLogging(Class<? extends Log> clazz) { setImplementation(clazz); } public static synchronized void useSlf4jLogging() { setImplementation(org.apache.ibatis.logging.slf4j.Slf4jImpl.class); } public static synchronized void useCommonsLogging() { setImplementation(org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl.class); } public static synchronized void useLog4JLogging() { setImplementation(org.apache.ibatis.logging.log4j.Log4jImpl.class); } public static synchronized void useLog4J2Logging() { setImplementation(org.apache.ibatis.logging.log4j2.Log4j2Impl.class); } public static synchronized void useJdkLogging() { setImplementation(org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl.class); } public static synchronized void useStdOutLogging() { setImplementation(org.apache.ibatis.logging.stdout.StdOutImpl.class); } public static synchronized void useNoLogging() { setImplementation(org.apache.ibatis.logging.nologging.NoLoggingImpl.class); } /** * 尝试加载实现类 * @param runnable */ private static void tryImplementation(Runnable runnable) { if (logConstructor == null) { try { runnable.run(); } catch (Throwable t) { // ignore } } } /** * 设置实现类方法 * @param implClass */ private static void setImplementation(Class<? extends Log> implClass) { try { //获取Log默认String 的构造参数 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 = candidate; } catch (Throwable t) { throw new LogException("Error setting Log implementation. Cause: " + t, t); } } }

__EOF__

本文作者lonecloud
本文链接https://www.cnblogs.com/lonecloud/p/14219184.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   lonecloud  阅读(225)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
我的博客即将同步至 OSCHINA 社区,这是我的 OSCHINA ID:lonecloud,邀请大家一同入驻:https://www.oschina.net/sharing-plan/apply
点击右上角即可分享
微信分享提示