Mybatis 拦截器实现原理

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在这里已经被修改成一个代理对象。

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

时间: 2024-10-04 00:20:13

Mybatis 拦截器实现原理的相关文章

Mybatis最入门---分页查询(拦截器分页原理及实现)

[一步是咫尺,一步即天涯] 前文,我们演示了物理分页的Sql实现方式,这种方式使得我们每次在编写查询服务时,不断的重复造轮子.这样的代码实现方式就显得十分的笨拙了.本文是Mybatis分页查询的最后一片内容,我们将介绍基于拦截器的,精巧的实现方式.在阅读这篇文章之前,强烈建议各位看官能够先阅读上文.这样就能对下文我们提及的各种对象及他们之间的关系有一个清晰的关系.好了,废话不多讲,开始我们的正文部分吧. 准备工作: a.操作系统 :win7 x64 b.基本软件:MySQL,Mybatis,SQ

MyBatis拦截器原理探究

前言: MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用.默认情况下,MyBatis 允许使用插件来拦截的方法调用包括: Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClose

Mybatis拦截器介绍及分页插件

1.1    目录 1.1 目录 1.2 前言 1.3 Interceptor接口 1.4 注册拦截器 1.5 Mybatis可拦截的方法 1.6 利用拦截器进行分页 1.2     前言 拦截器的一个作用就是我们可以拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,也可以在执行这些被拦截的方法时执行自己的逻辑而不再执行被拦截的方法.Mybatis拦截器设计的一个初衷就是为了供用户在某些时候可以实现自己的逻辑而不必去动Mybatis固有的逻辑.打个比方,对于Executor

Mybatis拦截器介绍

拦截器的一个作用就是我们可以拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,也可以在执行这些被拦截的方法时执行自己的逻辑而不再执行被拦截的方法.Mybatis拦截器设计的一个初衷就是为了供用户在某些时候可以实现自己的逻辑而不必去动Mybatis固有的逻辑.打个比方,对于Executor,Mybatis中有几种实现:BatchExecutor.ReuseExecutor.SimpleExecutor和CachingExecutor.这个时候如果你觉得这几种实现对于Execu

【Mybatis】1、Mybatis拦截器

MyBatis拦截器原理探究 http://www.cnblogs.com/fangjian0423/p/mybatis-interceptor.html MyBatis 拦截器 (实现分页功能) http://www.cnblogs.com/jethypc/p/5149183.html 由浅入深分析mybatis通过动态代理实现拦截器(插件)的原理 http://zhangbo-peipei-163-com.iteye.com/blog/2033832 使用方法 https://github.

Mybatis拦截器实现分页

本文介绍使用Mybatis拦截器,实现分页:并且在dao层,直接返回自定义的分页对象. 最终dao层结果: public interface ModelMapper { Page<Model> pageByConditions(RowBounds rowBounds, Model record); } 接下来一步一步来实现分页. 一.创建Page对象: public class Page<T> extends PageList<T> { private int page

【Mybatis】1、Mybatis拦截器学习资料汇总

MyBatis拦截器原理探究 http://www.cnblogs.com/fangjian0423/p/mybatis-interceptor.html [myBatis]Mybatis中的拦截器 http://blog.csdn.net/moshenglv/article/details/52699976 MyBatis 拦截器 (实现分页功能) http://www.cnblogs.com/jethypc/p/5149183.html 由浅入深分析mybatis通过动态代理实现拦截器(插件

Mybatis 拦截器(二)

Mybatis拦截器介绍 拦截器的一个作用就是我们可以拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,也可以在执行这些被拦截的方法时执行自己的逻辑而不再执行被拦截的方法.Mybatis拦截器设计的一个初衷就是为了供用户在某些时候可以实现自己的逻辑而不必去动Mybatis固有的逻辑.打个比方,对于Executor,Mybatis中有几种实现:BatchExecutor.ReuseExecutor.SimpleExecutor和CachingExecutor.这个时候如果你觉

mybatis拦截器

业务需求:由于公司业务需要在所有的sql的增删改查中必须包含officeId,业务以officeId做隔离.因此做了一个Mybatis的的过去器.通过拦截sql处理的过程来判断接口sql是否包含officeId,如果不包含则添加officeId.@NoNeedOffice的注解可以添加在Dao的接口类或方法上.用于标识不需要处理的接口. package com.example.springcloud.provider; import com.example.springcloud.provide