IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Mybatis 框架日志相关源码分析(二)

    此间少年发表于 2023-04-18 09:43:00
    love 0

    通过上篇文章《Mybatis 框架日志相关源码分析(一)》了解了 Mybatis 框架通过适配器模式,来整合其它日志框架。而我们都知道要想使用 Log 接口,就需要有具体的实现类对象,那么 Mybatis 是如何创建具体的实现类对象呢?

    本文将分析 Mybatis 框架的日志相关源码,了解 Mybatis 如何创建日志实现类对象。

    Mybatis 在解析到配置中的具体日志 Value 内容时,不仅保存了对应的 Class<? extends Log> 属性,还有一行代码:LogFactory.useCustomLogging(this.logImpl):

    public void setLogImpl(Class<? extends Log> logImpl) {
      if (logImpl != null) {
        this.logImpl = logImpl;
        LogFactory.useCustomLogging(this.logImpl);
      }
    }

    LogFactory 这个类可谓是见名知意,Log 工厂,在设计模式中,这明显就是工厂模式。继续深入看看,这个工厂里面到底是如何创建对象的。首先从入口方法 useCustomLogging 看起,此方法代码很简单,直接调用了 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);
      }
    }

    此方法的形参,对应的就是实现类的 Class 对象,首先获取了 Class 对象构造器,此构造器是带有一个形参为 String.class 。接着就是输出一些日志,最后,将此构造器对象,保存为静态属性:logConstructor 。当有外部代码需要输出日志,通过调用 getLog 方法即可实现日志输出:

    public static Log getLog(Class<?> clazz) {
      return getLog(clazz.getName());
    }
    
    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);
      }
    }

    至此,我们了解了 Mybatis 通过工厂模式创建日志适配类对象。其中 LogFactory 中保存的是日志适配类的构造器对象,通过调用 getLog 方法,此工厂才返回具体的实现类对象。



沪ICP备19023445号-2号
友情链接