1. Mybatis日志的工厂模式和适配器模式

1.日志模块的类图如下:
1. Mybatis日志的工厂模式和适配器模式_第1张图片

1.适配器模式

日志模块使用了适配器模式,各种日志框架适配Log接口:

NoLogginImpl:  无日志的实现,不打印日志直接返回
Sfl4jImpl: 适配Sfl4j的实现
Jdk14LoggingImpl: 适配使用Jdk Logging框架
JakartaCommonsLoggingImpl: 适配使用Apache Commons Logging
Log4jImpl: 适配Log4j
Log4j2Impl:适配Log4j2
StdOutImpl:适配直接使用System.out.println()打印日志

为了有更加直观的认识,下面展示Log4jImpl的代码:

package org.apache.ibatis.logging.log4j;

import org.apache.ibatis.logging.Log;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

//适配Log4j日志输出
public class Log4jImpl implements Log {
  
  private static final String FQCN = Log4jImpl.class.getName();
  //内部持有Log4j的Logger
  private final Logger log;

  public Log4jImpl(String clazz) {
    log = Logger.getLogger(clazz);
  }
  
  //下面是方法的适配
  @Override
  public boolean isDebugEnabled() {
    return log.isDebugEnabled();
  }

  @Override
  public boolean isTraceEnabled() {
    return log.isTraceEnabled();
  }

  @Override
  public void error(String s, Throwable e) {
    log.log(FQCN, Level.ERROR, s, e);
  }

  @Override
  public void error(String s) {
    log.log(FQCN, Level.ERROR, s, null);
  }

  @Override
  public void debug(String s) {
    log.log(FQCN, Level.DEBUG, s, null);
  }

  @Override
  public void trace(String s) {
    log.log(FQCN, Level.TRACE, s, null);
  }

  @Override
  public void warn(String s) {
    log.log(FQCN, Level.WARN, s, null);
  }

}

2.简单工厂模式

使用LogFactory根据配置生产不同的日志实现

配置的方法:
调用不同方法来设置工厂的日志构造函数

  //日志的构造函数反射类
  private static Constructor<? extends Log> logConstructor;
  
  /** 根据实现类,设置日志构造函数反射类 */
  private static void setImplementation(Class<? extends Log> implClass) {
    try {
      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);
    }
  }
}

/** 设置使用哪种日志实现,下同, 传入实现类 */
  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);
  }

获取日志:

  /** 获得日志实例 */
  public static Log getLog(String logger) {
    try {
     //通过反射new出日志对象并返回
      return logConstructor.newInstance(logger);
    } catch (Throwable t) {
      throw new LogException("Error creating logger for logger " + logger + ".  Cause: " + t, t);
    }
  }

你可能感兴趣的:(1. Mybatis日志的工厂模式和适配器模式)