一、插件的解析,所有插件都会被添加到 InterceptorChain 类中,用于后续处理

org.apache.ibatis.builder.xml.XMLConfigBuilder

  1. private void pluginElement(XNode parent) throws Exception {
  2. if (parent != null) {
  3. for (XNode child : parent.getChildren()) {
  4. String interceptor = child.getStringAttribute("interceptor");
  5. Properties properties = child.getChildrenAsProperties();
  6. Interceptor interceptorInstance = (Interceptor) resolveClass(interceptor).newInstance();
  7. interceptorInstance.setProperties(properties);
  8. configuration.addInterceptor(interceptorInstance);
  9. }
  10. }
  11. }

org.apache.ibatis.session.Configuration

  1. public void addInterceptor(Interceptor interceptor) {
  2. interceptorChain.addInterceptor(interceptor);
  3. }

二、四大对象的创建顺序,都会经过 interceptorChain.pluginAll() 进行处理

1.Executor,SQL语句执行器

org.apache.ibatis.session.Configuration

  1. public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
  2. executorType = executorType == null ? defaultExecutorType : executorType;
  3. executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
  4. Executor executor;
  5. if (ExecutorType.BATCH == executorType) {
  6. executor = new BatchExecutor(this, transaction);
  7. } else if (ExecutorType.REUSE == executorType) {
  8. executor = new ReuseExecutor(this, transaction);
  9. } else {
  10. executor = new SimpleExecutor(this, transaction);
  11. }
  12. if (cacheEnabled) {
  13. executor = new CachingExecutor(executor);
  14. }
  15. executor = (Executor) interceptorChain.pluginAll(executor);
  16. return executor;
  17. }

2.ParameterHandler,参数处理器

org.apache.ibatis.executor.statement.BaseStatementHandler

  1. protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
  2. this.configuration = mappedStatement.getConfiguration();
  3. this.executor = executor;
  4. this.mappedStatement = mappedStatement;
  5. this.rowBounds = rowBounds;
  6.  
  7. this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
  8. this.objectFactory = configuration.getObjectFactory();
  9.  
  10. if (boundSql == null) { // issue #435, get the key before calculating the statement
  11. generateKeys(parameterObject);
  12. boundSql = mappedStatement.getBoundSql(parameterObject);
  13. }
  14.  
  15. this.boundSql = boundSql;
  16.  
  17. this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);
  18. this.resultSetHandler = configuration.newResultSetHandler(executor, mappedStatement, rowBounds, parameterHandler, resultHandler, boundSql);
  19. }

org.apache.ibatis.session.Configuration

  1. public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
  2. ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
  3. parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
  4. return parameterHandler;
  5. }

3.ResultSetHandler,结果集处理器

org.apache.ibatis.executor.statement.BaseStatementHandler

  1. protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
  2. this.configuration = mappedStatement.getConfiguration();
  3. this.executor = executor;
  4. this.mappedStatement = mappedStatement;
  5. this.rowBounds = rowBounds;
  6.  
  7. this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
  8. this.objectFactory = configuration.getObjectFactory();
  9.  
  10. if (boundSql == null) { // issue #435, get the key before calculating the statement
  11. generateKeys(parameterObject);
  12. boundSql = mappedStatement.getBoundSql(parameterObject);
  13. }
  14.  
  15. this.boundSql = boundSql;
  16.  
  17. this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);
  18. this.resultSetHandler = configuration.newResultSetHandler(executor, mappedStatement, rowBounds, parameterHandler, resultHandler, boundSql);
  19. }

org.apache.ibatis.session.Configuration

  1. public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler, ResultHandler resultHandler, BoundSql boundSql) {
  2. ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds);
  3. resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);
  4. return resultSetHandler;
  5. }

4.StatementHandler,SQL语句处理器

org.apache.ibatis.executor.SimpleExecutor

  1. @Override
  2. public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
  3. Statement stmt = null;
  4. try {
  5. Configuration configuration = ms.getConfiguration();
  6. StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
  7. stmt = prepareStatement(handler, ms.getStatementLog());
  8. return handler.query(stmt, resultHandler);
  9. } finally {
  10. closeStatement(stmt);
  11. }
  12. }

org.apache.ibatis.session.Configuration

  1. public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
  2. StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);
  3. statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
  4. return statementHandler;
  5. }

三、多个不同类型插件的执行顺序

org.apache.ibatis.executor.SimpleExecutor

  1. @Override
  2. public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
  3. Statement stmt = null;
  4. try {
  5. Configuration configuration = ms.getConfiguration();
  6. StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
  7. stmt = prepareStatement(handler, ms.getStatementLog());
  8. // 3.执行 SQL 语句,封装结果集,ResultSetHandler 拦截插件执行
  9. return handler.query(stmt, resultHandler);
  10. } finally {
  11. closeStatement(stmt);
  12. }
  13. }
  14.  
  15. private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
  16. Statement stmt;
  17. Connection connection = getConnection(statementLog);
  18. // 1.准备语句,StatementHandler 拦截插件执行
  19. stmt = handler.prepare(connection, transaction.getTimeout());
  20. // 2.SQL 语句参数处理,ParameterHandler 拦截插件执行
  21. handler.parameterize(stmt);
  22. return stmt;
  23. }

四、多个相同类型插件的执行顺序,以  StatementHandler 为例

1.创建顺序,按照配置顺序层层代理,最后配置的插件为最外层代理

配置了两个插件

  1. <plugins>
  2. <plugin interceptor="com.plugins.ExamplePlugin"></plugin>
  3. <plugin interceptor="com.plugins.ExamplePlugin2"></plugin>
  4. </plugins>

1.1.准备创建

1.2.最开始要执行的对象

1.3.开始创建

1.4.创建完毕

2.执行顺序,按照配置顺序倒序执行

2.1.第一次执行,ExamplePlugin2

2.2.第二次执行,ExamplePlugin

2.3.最终执行

3.示意图

MyBatis-Plugins 的创建流程与执行顺序的更多相关文章

  1. 步步深入:MySQL架构总览->查询执行流程->SQL解析顺序

    前言: 一直是想知道一条SQL语句是怎么被执行的,它执行的顺序是怎样的,然后查看总结各方资料,就有了下面这一篇博文了. 本文将从MySQL总体架构--->查询执行流程--->语句执行顺序来 ...

  2. MySQL架构总览->查询执行流程->SQL解析顺序

    Reference:  https://www.cnblogs.com/annsshadow/p/5037667.html 前言: 一直是想知道一条SQL语句是怎么被执行的,它执行的顺序是怎样的,然后 ...

  3. 步步深入MySQL:架构->查询执行流程->SQL解析顺序!

    一.前言 一直是想知道一条SQL语句是怎么被执行的,它执行的顺序是怎样的,然后查看总结各方资料,就有了下面这一篇博文了. 本文将从MySQL总体架构--->查询执行流程--->语句执行顺序 ...

  4. Unity脚本在层级面板中的执行顺序测试1

    第二篇测试循环时和动态创建时的调用顺序:LINK 测试版本Unity4.6.因为新版本对Transform的排序做了改变,所以不排除旧版本的测试结果不一样.测试时,使用Awake中添加Debug.lo ...

  5. python—day15 包的认识、执行顺序、执行流程、循环导入、包的导入、绝对、相对导入

    一.包的认识   包通过文件夹来管理一系列功能相近的模块 ​ 包:一系列模块的集合体 重点:包中一定有一个专门用来管理包中所有模块的文件 包名:存放一系列模块的文件夹名字 包名(包对象)存放的是管理模 ...

  6. Python流程控制-1 顺序执行

    流程控制指的是代码运行逻辑.分支走向.循环控制,是真正体现我们程序执行顺序的操作.流程控制一般分为顺序执行.条件判断和循环控制. 顺序执行 Python代码在执行过程中,遵循下面的基本原则: 普通语句 ...

  7. mirantis fuel puppet执行顺序 和 对整个项目代码的执行流程理解

    stage执行顺序 stage {'zero': } -> stage {'first': } -> stage {'openstack-custom-repo': } -> sta ...

  8. 创建HttpFilter与理解多个Filter代码的执行顺序

    1.自定义的HttpFilter,实现Filter接口 HttpFilter package com.aff.filter; import java.io.IOException; import ja ...

  9. java-mybaits-013-mybatis-Interceptor-拦截器执行顺序

    一.概述 已知拦截器能够拦截四种类型:Executor.ParameterHandler.ResultSetHandler.StatementHandler. 1.1.不同类型拦截器的执行顺序 背景: ...

随机推荐

  1. Json.net 反序列化 部分对象

    主要通过 Jobject获取想要序列化的部分对象. 直接上代码 static void Main(string[] args) { //先反序列化看看 string json = "{\&q ...

  2. BZOJ5296 [CQOI2018] 破解D-H协议 【数学】【BSGS】

    题目分析: 裸题. 代码: #include<bits/stdc++.h> using namespace std; typedef long long ll; ; #define mp ...

  3. Linux的Shell练习--个人笔记

    一. 实验准备(预防抄袭,此步必做) 1. 请将提示符设为:学号加波浪号.输入PS1=学号~,如PS1=110015~, 回车执行 2. 如发现提示符.学号不匹配, 视为抄袭或无效 二. 实验项目 1 ...

  4. 面向对象—的__new__()方法详解

    [Python] Python 之 __new__() 方法与实例化   __new__() 是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解,在 Python 中存在于类里面的构 ...

  5. 【BZOJ3999】【TJOI2015】旅游 树剖

    题目大意 给你一棵树,有\(n\)个点.有\(q\)个操作,每次要你从\(x\)到\(y\)的路径上选两个点,使得距离\(x\)比较远的点的点权\(-\)距离\(x\)比较近的点的点权最大,然后把这条 ...

  6. yoj维护

    维护 启动容器 docker start yoj 暂停容器 docker stop yoj 重启容器 docker restart yoj 进入容器的终端 docker attach yok 保存容器 ...

  7. Min_25

    可以用来筛出一个积性函数的前缀和.这个积性函数要满足当\(x\)是质数时,\(f(x)\)可以快速求出,\(f(x^k)\)也可以快速算出. 首先我们要处理出一个\(g(x)=\sum_{x\in p ...

  8. 字符串数据结构模板/题单(后缀数组,后缀自动机,LCP,后缀平衡树,回文自动机)

    模板 后缀数组 #include<bits/stdc++.h> #define R register int using namespace std; const int N=1e6+9; ...

  9. 【CF671D】Roads in Yusland(贪心,左偏树)

    [CF671D]Roads in Yusland(贪心,左偏树) 题面 洛谷 CF 题解 无解的情况随便怎么搞搞提前处理掉. 通过严密(大雾)地推导后,发现问题可以转化成这个问题: 给定一棵树,每条边 ...

  10. 【BZOJ5318】[JSOI2018]扫地机器人(动态规划)

    [BZOJ5318][JSOI2018]扫地机器人(动态规划) 题面 BZOJ 洛谷 题解 神仙题.不会.... 先考虑如果一个点走向了其下方的点,那么其右侧的点因为要被访问到,所以必定只能从其右上方 ...