码迷,mamicode.com
首页 > 其他好文 > 详细

Mybatis 拦截器实现原理

时间:2019-07-23 15:19:57      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:创建   code   编写   ret   exe   parent   set   lse   有一个   

Mybatis 拦截器实现原理

标签(空格分隔): mybatis


拦截器概述

  • 像springmvc一样,mybatis也提供了拦截器实现,只是他们拦截的对象不同。
  • mybatis给Executor、StatementHandler、ResultSetHandler、ParameterHandler提供了拦截器功能,
    • Executor提供了增删改查的接口.
    • StatementHandler负责处理Mybatis与JDBC之间Statement的交互.
    • ResultSetHandler负责处理Statement执行后产生的结果集,生成结果列表.
    • ParameterHandler是Mybatis实现Sql入参设置的对象。
  • 拦截器采用了责任链模式,把请求发送者和请求处理者分开,各司其职。

立即开始

<plugins>
    <plugin interceptor="com.tamguo.demo.interceptor.StatementInterceptor"></plugin>
</plugins>

@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class StatementInterceptor implements Interceptor {

    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println(" hello Statement interceptor !");
        return invocation.proceed();
    }

    public Object plugin(Object target) {
        Object wrap = Plugin.wrap(target, this);
        return wrap;
    }

    public void setProperties(Properties properties) {

    }
}

开始一个Statement拦截器,在mybatis-config.xml加入plugin配置,编写一个StatementInterceptor类。这样就已经完成了一个拦截器的编写,该类会链接StatementHandler的prepare方法。

MyBatis 加载intercetor过程

技术图片

pluginElement() 是Confiration中,解析XML并把interceptorInstance加入到interceptorChain。

   private void pluginElement(XNode parent) throws Exception {
    if (parent != null) {
      for (XNode child : parent.getChildren()) {
        String interceptor = child.getStringAttribute("interceptor");
        Properties properties = child.getChildrenAsProperties();
        Interceptor interceptorInstance = (Interceptor) resolveClass(interceptor).newInstance();
        interceptorInstance.setProperties(properties);
        configuration.addInterceptor(interceptorInstance);
      }
    }
  }
  

到这里Confiration对象已经持有了一个InterceptorChain属性, InterceptorChain中只有一个intercetor的list集合。

sqlSessionFactory.openSession(),会创建Executor、StatementHandler、ResultSetHandler、ParameterHandler对象。

  public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
    executorType = executorType == null ? defaultExecutorType : executorType;
    executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
    Executor executor;
    if (ExecutorType.BATCH == executorType) {
      executor = new BatchExecutor(this, transaction);
    } else if (ExecutorType.REUSE == executorType) {
      executor = new ReuseExecutor(this, transaction);
    } else {
      executor = new SimpleExecutor(this, transaction);
    }
    if (cacheEnabled) {
      executor = new CachingExecutor(executor);
    }
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
  }
  

executor = (Executor) interceptorChain.pluginAll(executor); 注意这一行代码,executor在这里已经被修改成一个代理对象。

Mybatis 拦截器实现原理

标签:创建   code   编写   ret   exe   parent   set   lse   有一个   

原文地址:https://www.cnblogs.com/tamguo/p/11231651.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!