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適配器內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 手把手教你從零設計一個java日志框架
- org.slf4j.Logger中info()方法的使用詳解
- 詳解記錄Java Log的幾種方式
- 圖文詳解SpringBoot中Log日志的集成
- 解決springmvc整合Mybatis的Log4j日志輸出問題