首頁 > 軟體

Mybatis紀錄檔模組的介面卡模式詳解

2022-08-09 18:00:38

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介面卡內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com