zoukankan      html  css  js  c++  java
  • 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上下位置,输出一致

      

      

      

      

    但是

  • 相关阅读:
    指针
    基本数据类型和string类型的转换
    golang的数据类型之基本数据类型的默认值和转换
    golang的数据类型之字符串类型
    golang的数据类型之布尔类型
    windows pyspider WEB显示框太小解决方法
    MYSQL的全局变量和会话变量
    php 日期计算 总结
    使用 PHPMailer 发送邮件
    MySQL两种表存储结构MyISAM和InnoDB的性能比较测试
  • 原文地址:https://www.cnblogs.com/bjlhx/p/11263268.html
Copyright © 2011-2022 走看看