一、概述

  已知拦截器能够拦截四种类型:Executor、ParameterHandler、ResultSetHandler、StatementHandler。

1.1、不同类型拦截器的执行顺序

背景:不同类型

项目地址:https://github.com/bjlhx15/mybatis.git 中的mybatis-interceptor-001 基础项目

顺序【Executor→StatementHandler→ParameterHandler→ResultSetHandler】

1、编写拦截器代码

  

2、mybatis.xml配置

    <plugins>
<!-- 拦截器配置 -->
<plugin interceptor="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.TestTypeInterceptorParameterHandler"/>
<plugin interceptor="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.TestTypeInterceptorResultSetHandler"/>
<plugin interceptor="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.TestTypeInterceptorStatementHandler"/>
<plugin interceptor="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.TestTypeInterceptorExecutor"/>
</plugins>

3、执行测试输出

TestTypeInterceptorExecutor
[2019-07-29 10:37:25:540-http-nio-8080-exec-1] [INFO] - com.alibaba.druid.pool.DruidDataSource.init(DruidDataSource.java:930) - {dataSource-1} inited
TestTypeInterceptorStatementHandler
[2019-07-29 10:37:29:827-http-nio-8080-exec-1] [DEBUG] - org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:145) - ==> Preparing: select 'true' as QUERYID, id, name, version, balance from accountbalance
TestTypeInterceptorParameterHandler
[2019-07-29 10:37:31:177-http-nio-8080-exec-1] [DEBUG] - org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:145) - ==> Parameters:
TestTypeInterceptorResultSetHandler

  可以看到不论配置文件如何,执行顺序如下:【Executor→StatementHandler→ParameterHandler→ResultSetHandler】

    

1.2、同类型位置不同

背景:同类型位置不同

项目地址:https://github.com/bjlhx15/mybatis.git 中的mybatis-interceptor-002 基础项目

顺序:数组上下位置倒序【3拦截前处理 > 2拦截前处理 > 1拦截前处理 > executor.query() > 1拦截后处理 > 2拦截后处理 > 3拦截后处理】

1、编写拦截器

  

2、编写xml

    <plugins>
<!-- 拦截器配置 -->
<plugin interceptor="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.Test1Interceptor"/>
<plugin interceptor="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.Test2Interceptor"/>
</plugins> 

3、执行测试输出

Test2Interceptor
Test1Interceptor

4、why

  查看mybatis配置org.apache.ibatis.session.Configuration。中创建

    public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? this.defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Object 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 (this.cacheEnabled) {
executor = new CachingExecutor((Executor)executor);
} Executor executor = (Executor)this.interceptorChain.pluginAll(executor);
return executor;
}

  interceptorChain是在Configuration类中new出来的。它等价于mybatis-config中的<plugins></plugins>

  查看 pluginAll添加顺序

    private final List<Interceptor> interceptors = new ArrayList();

    public InterceptorChain() {
} public Object pluginAll(Object target) {
Interceptor interceptor;
for(Iterator i$ = this.interceptors.iterator(); i$.hasNext(); target = interceptor.plugin(target)) {
interceptor = (Interceptor)i$.next();
} return target;
}

  可以看到 interceptorChain 拦截器顺序就是 配置顺序

  

  但是在经过代理后,

  

3拦截前处理 > 2拦截前处理 > 1拦截前处理 > executor.query() > 1拦截后处理 > 2拦截后处理 > 3拦截后处理

1.3、同类型不同配置位置

背景:有spring中配置,还有mybatis中配置

项目地址:https://github.com/bjlhx15/mybatis.git 中的mybatis-interceptor-002 基础项目

顺序:数组上下位置倒序【mybatis配置拦截器2 > mybatis配置拦截器1 > spring配置拦截器2 >spring配置拦截器1 > executor.query() > spring配置拦截器1 > spring配置拦截器2 >  mybatis配置拦截器1 > mybatis配置拦截器2 

1、编写拦截器

2、spring中xml配置

    <bean id="wrSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 实例化sqlSessionFactory时需要使用上述配置好的数据源以及SQL映射文件 -->
<property name="dataSource" ref="wrDataSource"/>
<property name="mapperLocations" value="classpath:mapper/auto/**/*.xml"/>
<!-- mybatis的全局配置文件 如没有特需 可以不配置 -->
<property name="plugins">
<array>
<bean class="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.TestnterceptorIString1"/>
<bean class="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.TestnterceptorIString2"/>
</array>
</property>
<property name="configLocation" value="classpath:mybatis.xml"/>
</bean>

mybatis中配置

<?xml version="1.0"  encoding="UTF-8"  ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration>
<plugins>
<!-- 拦截器配置 -->
<plugin interceptor="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.TestInterceptorMybatis1"/>
<plugin interceptor="com.github.bjlhx15.mybatis.readwrite.split.mybatisinterceptor.TestInterceptorMybatis2"/>
</plugins> </configuration>

3、输出

TestInterceptorMybatis2
TestInterceptorMybatis1
TestnterceptorIString2
TestnterceptorIString1

可以调整 spring中configLocation和plugins上下位置,输出一致

  

  

  

  

但是

java-mybaits-013-mybatis-Interceptor-拦截器执行顺序的更多相关文章

  1. Mybatis Interceptor 拦截器原理 源码分析

    Mybatis采用责任链模式,通过动态代理组织多个拦截器(插件),通过这些拦截器可以改变Mybatis的默认行为(诸如SQL重写之类的),由于插件会深入到Mybatis的核心,因此在编写自己的插件前最 ...

  2. mybatis Interceptor拦截器代码详解

    mybatis官方定义:MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis ...

  3. SpringMVC自定义多个拦截器执行顺序

    一.正常流程下的拦截器(全部放行) 1.springMVC中拦截器实现这个接口HandlerInterceptor 第一个拦截器 HandlerInterceptor1   public class ...

  4. Struts2的默认拦截器执行顺序

    我们在写Struts2的时候package属性默认都是差不多这样吧 <package name="packageName" namespace="/" e ...

  5. Springmvc的拦截器执行顺序及各方法作用

    实现HandlerInterceptor接口或者继承HandlerInterceptor的子类,比如Spring 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInt ...

  6. Mybatis拦截器执行过程解析

    上一篇文章 Mybatis拦截器之数据加密解密 介绍了 Mybatis 拦截器的简单使用,这篇文章将透彻的分析 Mybatis 是怎样发现拦截器以及调用拦截器的 intercept 方法的 小伙伴先按 ...

  7. SpringMVC 中的Interceptor 拦截器

    1.配置拦截器 在springMVC.xml配置文件增加: <mvc:interceptors>  <!-- 日志拦截器 -->  <mvc:interceptor> ...

  8. Mybatis之拦截器原理(jdk动态代理优化版本)

    在介绍Mybatis拦截器代码之前,我们先研究下jdk自带的动态代理及优化 其实动态代理也是一种设计模式...优于静态代理,同时动态代理我知道的有两种,一种是面向接口的jdk的代理,第二种是基于第三方 ...

  9. MyBatis实现拦截器分页功能

    1.原理 在mybatis使用拦截器(interceptor),截获所执行方法的sql语句与参数. (1)修改sql的查询结果:将原sql改为查询count(*) 也就是条数 (2)将语句sql进行拼 ...

  10. Spring中的Interceptor 拦截器 专题

    spring-webmvc-4.3.14.RELEASE.jar org.springframework.web.servlet.DispatcherServlet#doDispatch /** * ...

随机推荐

  1. linux网络编程之posix条件变量

    今天来学习posix的最后一个相关知识----条件变量,言归正传. 下面用一个图来进一步描述条件变量的作用: 为什么呢? 这实际上可以解决生产者与消费者问题,而且对于缓冲区是无界的是一种比较理解的解决 ...

  2. Java8新特性--函数式编程

    在jdk8中什么是函数式接口: 1.被@FunctionalInterface注解修饰的. 2.接口里边只有一个非default的方法. 满足以上2个条件的即为函数式接口,ps:即使一个接口没有被@F ...

  3. java只能的round,ceil,floor方法的使用

    三者均位于java.lange包下的Math类中 round: 在原来数字的基础上加上0.5后向下取整, 例如: Math.floor(11.5)=12; Math.floor(-11.5)=-11( ...

  4. 在 windows 上安装 git 2.15

    下载 by win 下载地址:https://git-scm.com/download/win 如下图.选择对应的版本下载: 安装 by win 1.双击下载好的git安装包.弹出提示框.如下图: 2 ...

  5. window.frameElement

    地址:MDN web docs 比如有一个iframe的src是xxx.htmframeElement的作用就是在xxx.htm中获得这个引用它的iframe objet这样你就可以在xxx.htm改 ...

  6. [Javascript] Construct a Regex to Match Twitter Mentions with Regexr

    regexr is a powerful tool for debugging existing regexes and creating new ones. In this lesson, we'l ...

  7. element案例大杂烩

    修改表头字体粗细? <el-table :data="list" header-row-class-name="tableHead"> 自定义即可 ...

  8. Centos 安装JDK(最最最最最方便的方法)

    1.下载rpm安装文件,链接:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 2 ...

  9. React应用数据传递的方式

    1. props属性 典型的React应用,数据通过props按照自上而下(父->子)的顺序传递数据. 2. Context传值 1. 应用场景 对于一些应用中全局性的属性(如UI主题.语言.登 ...

  10. java上传文件夹文件

    这里只写后端的代码,基本的思想就是,前端将文件分片,然后每次访问上传接口的时候,向后端传入参数:当前为第几块文件,和分片总数 下面直接贴代码吧,一些难懂的我大部分都加上注释了: 上传文件实体类: 看得 ...