Java Mybatis日志工厂(没有日志jar不报错)

说明

Mybatis框架,如果没有日志 jar 包,就不会打印日志,也不会报错

加上 日志 jar包(还要有相关配置文件),就会打印日志

这和我们使用的日志不同,我们使用日志时,必须有jar包,否则就会报错找不到类

Mybatis实现原理

Mybatis 的 logging 包下,都是跟日志相关的类

Log

是使用日志的接口,通过该接口打印日志

LogFactory

Log工厂,也是核心

加载日志框架

使用该类时,会先加载日志框架,如下:

优先加载顺序:

  • Slf4j
  • CommonsLogging:Tomcat自带的日志
  • Log4J2
  • Log4J
  • Jdk自带的日志
  • NoLogging:没有日志

tryImplementation()

形参是 Runnable,其目的是函数式编程,可以像上图那样,通过 LogFactory::useLog4JLogging 传入方法

在 catch{} 代码块中,没有打印异常信息

  private static void tryImplementation(Runnable runnable) {
    if (logConstructor == null) {
      try {
        runnable.run();
      } catch (Throwable t) {
        // ignore
      }
    }
  }

useLog4JLogging()

以 log4j 为例,useLog4JLogging() 代码如下:

public static synchronized void useLog4JLogging() {
    setImplementation(Log4jImpl.class);
}

加载的是 Log4jImpl.class 类

setImplementation() 方法

源码如下:

  private static void setImplementation(Class<? extends Log> implClass) {
    try {
      // 获取 Log4jImpl.class 类的构造方法,该构造方法有一个形参,其类型是 String
      Constructor<? extends Log> candidate = implClass.getConstructor(String.class);
      // 调用该构造方法创建 日志对象,传入 LogFactory 类全名,其目的是为了下面打印日志
      Log log = candidate.newInstance(LogFactory.class.getName());
      // 如果是 debug 级,就执行打印
      if (log.isDebugEnabled()) {
        log.debug("Logging initialized using '" + implClass + "' adapter.");
      }
      // 将构造对象传成静态变量,供 getLog() 方法使用
      logConstructor = candidate;
    } catch (Throwable t) {
      // 如果抛异常,就抛错,但在 tryImplementation() 方法的 catch{} 代码块没有打印异常,所以这里抛错也没意义
      throw new LogException("Error setting Log implementation.  Cause: " + t, t);
    }
  }

Log4jImpl 类

是对 log4j 的简单封装

构造方法

被调用:在 setImplementation() 方法中,获取该类的构造方法,该构造方法有一个形参,其类型是 String

作用:创建log4j的 Logger 对象

  public Log4jImpl(String clazz) {
    log = Logger.getLogger(clazz);
  }

其他方法

不多做解释,就是调用 log4j 的相关方法打印日志

为什么没有日志jar不报错

Log4jImpl 类中 import log4j 的类,如下:

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

为什么没有 log4j 的 jar 包,不会报 找不到类的异常?

原因:只要不调用 LogFactory 类,就不会调用 Log4jImpl 类,也就不会报 找不到类的异常

参考:
https://blog.csdn.net/qq_44041944/article/details/119799019


原文出处:/show_1IX74Wt2cKGf.html