java-mybaits-013-mybatis-Interceptor-拦截器执行顺序
一、概述
已知拦截器能够拦截四种类型: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-拦截器执行顺序的更多相关文章
- Mybatis Interceptor 拦截器原理 源码分析
Mybatis采用责任链模式,通过动态代理组织多个拦截器(插件),通过这些拦截器可以改变Mybatis的默认行为(诸如SQL重写之类的),由于插件会深入到Mybatis的核心,因此在编写自己的插件前最 ...
- mybatis Interceptor拦截器代码详解
mybatis官方定义:MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis ...
- SpringMVC自定义多个拦截器执行顺序
一.正常流程下的拦截器(全部放行) 1.springMVC中拦截器实现这个接口HandlerInterceptor 第一个拦截器 HandlerInterceptor1 public class ...
- Struts2的默认拦截器执行顺序
我们在写Struts2的时候package属性默认都是差不多这样吧 <package name="packageName" namespace="/" e ...
- Springmvc的拦截器执行顺序及各方法作用
实现HandlerInterceptor接口或者继承HandlerInterceptor的子类,比如Spring 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInt ...
- Mybatis拦截器执行过程解析
上一篇文章 Mybatis拦截器之数据加密解密 介绍了 Mybatis 拦截器的简单使用,这篇文章将透彻的分析 Mybatis 是怎样发现拦截器以及调用拦截器的 intercept 方法的 小伙伴先按 ...
- SpringMVC 中的Interceptor 拦截器
1.配置拦截器 在springMVC.xml配置文件增加: <mvc:interceptors> <!-- 日志拦截器 --> <mvc:interceptor> ...
- Mybatis之拦截器原理(jdk动态代理优化版本)
在介绍Mybatis拦截器代码之前,我们先研究下jdk自带的动态代理及优化 其实动态代理也是一种设计模式...优于静态代理,同时动态代理我知道的有两种,一种是面向接口的jdk的代理,第二种是基于第三方 ...
- MyBatis实现拦截器分页功能
1.原理 在mybatis使用拦截器(interceptor),截获所执行方法的sql语句与参数. (1)修改sql的查询结果:将原sql改为查询count(*) 也就是条数 (2)将语句sql进行拼 ...
- Spring中的Interceptor 拦截器 专题
spring-webmvc-4.3.14.RELEASE.jar org.springframework.web.servlet.DispatcherServlet#doDispatch /** * ...
随机推荐
- linux网络编程之posix条件变量
今天来学习posix的最后一个相关知识----条件变量,言归正传. 下面用一个图来进一步描述条件变量的作用: 为什么呢? 这实际上可以解决生产者与消费者问题,而且对于缓冲区是无界的是一种比较理解的解决 ...
- Java8新特性--函数式编程
在jdk8中什么是函数式接口: 1.被@FunctionalInterface注解修饰的. 2.接口里边只有一个非default的方法. 满足以上2个条件的即为函数式接口,ps:即使一个接口没有被@F ...
- java只能的round,ceil,floor方法的使用
三者均位于java.lange包下的Math类中 round: 在原来数字的基础上加上0.5后向下取整, 例如: Math.floor(11.5)=12; Math.floor(-11.5)=-11( ...
- 在 windows 上安装 git 2.15
下载 by win 下载地址:https://git-scm.com/download/win 如下图.选择对应的版本下载: 安装 by win 1.双击下载好的git安装包.弹出提示框.如下图: 2 ...
- window.frameElement
地址:MDN web docs 比如有一个iframe的src是xxx.htmframeElement的作用就是在xxx.htm中获得这个引用它的iframe objet这样你就可以在xxx.htm改 ...
- [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 ...
- element案例大杂烩
修改表头字体粗细? <el-table :data="list" header-row-class-name="tableHead"> 自定义即可 ...
- Centos 安装JDK(最最最最最方便的方法)
1.下载rpm安装文件,链接:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 2 ...
- React应用数据传递的方式
1. props属性 典型的React应用,数据通过props按照自上而下(父->子)的顺序传递数据. 2. Context传值 1. 应用场景 对于一些应用中全局性的属性(如UI主题.语言.登 ...
- java上传文件夹文件
这里只写后端的代码,基本的思想就是,前端将文件分片,然后每次访问上传接口的时候,向后端传入参数:当前为第几块文件,和分片总数 下面直接贴代码吧,一些难懂的我大部分都加上注释了: 上传文件实体类: 看得 ...