加入收藏 | 设为首页 | 会员中心 | 我要投稿 西安站长网 (https://www.029zz.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

Mybatis超详细插件机制解析,弄懂拦截器So easy

发布时间:2019-12-26 16:52:00 所属栏目:建站 来源:站长网
导读:副标题#e# 概述 Mybatis插件又称拦截器,本篇文章中出现的拦截器都表示插件。 Mybatis采用责任链模式,通过动态代理组织多个插件(拦截器),通过这些插件可以改变Mybatis的默认行为(诸如SQL重写之类的),由于插件会深入到Mybatis的核心,因此在编写自己的插

public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler, ResultHandler resultHandler, BoundSql boundSql) { 

  ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds); 

  resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler); 

  return resultSetHandler; 

查看源码可以发现, Mybatis框架在创建好这四大接口对象的实例后,都会调用InterceptorChain.pluginAll()方法。InterceptorChain对象是插件执行链对象,看源码就知道里面维护了Mybatis配置的所有插件(Interceptor)对象。

// target --> Executor/ParameterHandler/ResultSetHander/StatementHandler 

public Object pluginAll(Object target) { 

  for (Interceptor interceptor : interceptors) { 

   target = interceptor.plugin(target); 

  } 

  return target; 

其实就是按顺序执行我们插件的plugin方法,一层一层返回我们原对象(Executor/ParameterHandler/ResultSetHander/StatementHandler)的代理对象。当我们调用四大接口的方法的时候,实际上是调用代理对象的相应方法,代理对象又会调用四大接口的实例。

Plugin对象

我们知道,官方推荐插件实现plugin方法为:Plugin.wrap(target, this);

public static Object wrap(Object target, Interceptor interceptor) { 

  // 获取插件的Intercepts注解 

  Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor); 

  Class<?> type = target.getClass(); 

  Class<?>[] interfaces = getAllInterfaces(type, signatureMap); 

  if (interfaces.length > 0) { 

   return Proxy.newProxyInstance(type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap)); 

  } 

  return target; 

这个方法其实是Mybatis简化我们插件实现的工具方法。其实就是根据当前拦截的对象创建了一个动态代理对象。代理对象的InvocationHandler处理器为新建的Plugin对象。

插件配置注解@Intercepts

(编辑:西安站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读