Mybatis日志模块的适配器模式详解

 

Mybatis的日志模块的适配器模式

我们在开发中日志是必不可少的一部分,而市场中有很多日志框架供我们使用,mybatis作为一个开源框架需要兼容这些框架,mybatis用了适配器模式来兼容这些框架,适配器模式就是通过组合的方式,将需要适配的类转为使用者能够使用的接口

下面咱们分析一下mybatis的日志模块

mybatis定义了自己的Log接口

 

Log接口

public interface Log {
boolean isDebugEnabled();
boolean isTraceEnabled();
void error(String s, Throwable e);
void error(String s);
void debug(String s);
void trace(String s);
void warn(String s);
}

这里定义了一些常用的方法

LogFactory的静态代码块加载对应是日志适配器:

 

日志工厂类LogFactory

    static {
      tryImplementation(LogFactory::useSlf4jLogging);
      tryImplementation(LogFactory::useCommonsLogging);
      tryImplementation(LogFactory::useLog4J2Logging);
      tryImplementation(LogFactory::useLog4JLogging);
      tryImplementation(LogFactory::useJdkLogging);
      tryImplementation(LogFactory::useNoLogging);
  }
  private static void tryImplementation(Runnable runnable) {
      if (logConstructor == null) {
          try {
              runnable.run();
          } catch (Throwable t) {
              // ignore
          }
      }
  }
  public static synchronized void useLog4JLogging() {
      setImplementation(org.apache.ibatis.logging.log4j.Log4jImpl.class);
  }

当logConstructor用来记录日志适配器的构造方法,当logConstructor不为空的时候就不再加载其他的日志适配器了。

分析一下setImplementation()方法:

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);
      }
  }
  • 获取适配器的构造方法
  • 然后获取这个适配器的实例,如果获取成功,把它的构造方法记录在logConstructor中,否则就会抛出异常

下面就分析一下Log4jImpl类:

 

Log接口的实现类

public class Log4jImpl implements Log {
private static final String FQCN = Log4jImpl.class.getName();
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);
}

}

Log4jImpl是一个适配器类,它实现了Mybatis自定义的Log接口,它的成员变量Logger是log4j里的类,我们要做的是调用Log接口的方法就可以使用log4j,Logger是需要我们适配的类,因此我们在实现Log接口的方法的时候调用Logger中的方法来完成适配,这就是适配器模式的实现

 

总结

Mybatis日志模块用到了适配器模式,Log接口是目标接口,Logger等各种日志框架的类是需要我们适配的类,而是适配器是Log4jImpl、Slf4jImpl等适配类

关于Mybatis日志模块的适配器模式详解的文章就介绍至此,更多相关Mybatis适配器内容请搜索编程宝库以前的文章,希望以后支持编程宝库

 简介说明本文介绍Mybatis-Plus无法将字段更新为null的原因及解决方法。 问题描述用Mybatis-Plus的upda ...