一、概述

  已知拦截器能够拦截四种类型: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. jmeter+jenkins 配置过程(很详细)

    一.安装jmeter 第一步  安装JDK,配置JDK路径.注:jdk下载地址,推荐使用jdk1.8版本 http://www.oracle.com/technetwork/java/javase/d ...

  2. 透过CountDownLatch窥探AQS

    本文来自公众号“Kahuna”,可搜索Alitaba119,欢迎关注,转载请注明出处,非常感谢 “ A synchronization aid that allows one or more thre ...

  3. 浅析Scrapy框架运行的基本流程

    本篇博客将从Twisted的下载任务基本流程开始介绍,然后再一步步过渡到Scrapy框架的基本运行流程,其中还会需要我们自定义一个Low版的Scrapy框架.但内容不会涉及太多具体细节,而且需要注意的 ...

  4. python - django (session)

    # """ # Session # 是存在服务端的键值对 # Session 必须依赖Cookie 存储Session: · 在服务器生成随机字符串 · 生成一个和上面随 ...

  5. LightOJ - 1116-Ekka Dokka(思维)

    链接: https://vjudge.net/problem/LightOJ-1116 题意: Ekka and his friend Dokka decided to buy a cake. The ...

  6. struts2--CRUD

    struts的CRUD 1.导入相关的pom依赖(struts.自定义标签库的依赖) <dependency> <groupId>jstl</groupId> &l ...

  7. PHP 根据域名和IP返回不同的内容

    遇到一个好玩的事情,访问别人的IP和别人的域名返回的内容竟然不一样.突然觉得很好玩,也很好奇.自己研究了一下下,就简单写一下吧~ 一个IP和一个域名, 先讲一下公网IP没有绑定域名,但是可以通过一个没 ...

  8. HTML 文字剧中

    HTML 内想使文字剧中的办法  就是 text-align:center 剧中前效果图 剧中后效果图 代码:

  9. Cogs 12. 运输问题2(有上下界的有源汇最大流)

    运输问题2 ★★☆ 输入文件:maxflowb.in 输出文件:maxflowb.out 简单对比 时间限制:1 s 内存限制:128 MB 运输问题 [问题描述] 一个工厂每天生产若干商品,需运输到 ...

  10. P2543 [AHOI2004]奇怪的字符串

    题目描述 输入输出格式 输入格式: 输入文件中包含两个字符串X和Y.当中两字符串非0即1.序列长度均小于9999. 输出格式: X和Y的最长公共子序列长度. 输入输出样例 输入样例#1: 复制 010 ...