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上下位置,输出一致

 

  

 

  

 

  

 

  

 

 

 

 

 

 

 

但是

posted @ 2019-07-29 12:53  bjlhx15  阅读(3338)  评论(0编辑  收藏  举报
Copyright ©2011~2020 JD-李宏旭