Interceptor拦截器的源码解析:自定义Mybatis拦截器与Plugin

32 篇文章 0 订阅
订阅专栏

上一篇:Mybatis,动态代理CRUD源码分析

目录

1. 引言

2. 自定义插件的编写逻辑:根据Mybatis规则 编写一个拦截器,在拦截器内部加入自定义增强功能

2.1 编写拦截器

2.2 拦截器还要配置到mybatis里面,这里使用注解@Intercepts

2.3 在mybatis-config.xml文件中配置

 2.4 测试

 3. 配置多个拦截器

4. 拦截器的作用

5. 修改参数

5.1 写拦截器

完整MyInterceptor



1. 引言

上一篇中的Mybatis底层的四个处理器:StatementHandler 、ParameterHandler、ResultSetHandler、 TypeHandler

插件也涉及到4个核心对象StatementHandler 、ParameterHandler、ResultSetHandler、Executor

回顾mybatis动态代理对象进行增删改查操作

 mapper.queryStudentById()方法添加断点,调试进入方法内部

调用了invoke()方法,

 进入execute()方法

 进入selectOne()方法

 进入selectList()方法

 进入executor.query()方法

进入delegate.query()方法

 进入queryFromDatabase()方法

 进入doQuery()方法,在该方法可以看到我们的核心对象:StatementHandler

 进入newStatementHandler(),把处理器statementHandlerinterceptorChain.pluginAll(),该方法增强处理器statementHandler

拦截器类似于如下逻辑:

进入interceptorChain.pluginAll();

 可以看到拦截器Interceptor接口在org.apache.ibatis.plugin包下

 上诉拦截器,4个核心对象StatementHandler 、ParameterHandler、ResultSetHandler、Executor)都有

 四大核心对象:都涉及到了拦截器 用于增强 ,四大核心对象都包含了 该增强操作

2. 自定义插件的编写逻辑:根据Mybatis规则 编写一个拦截器,在拦截器内部加入自定义增强功能

        自定义插件编写步骤:

2.1 编写拦截器

 实现刚刚提到的拦截器:Interceptor接口,注意在org.apache.ibatis.plugin接口中:

 

 

可以看到interceptor接口有3个方法:intercepted()、plugin()、setProperties()。

 1. 先来看intercept()方法的放行方法:invoccation.proceed()

 

 2.  再来看plugin()方法

plugin()方法将拦截器中定义的增强功能和4大核心对象封装成一个整体

 3. 最后setProperties()方法

2.2 拦截器还要配置到mybatis里面,这里使用注解@Intercepts

@Intercepts注解中使用{}添加@Signature注解

拦截器可以拦截4大核心对象(StatementHandler、ParameterHandler、ResultSetHandler、Execute)其中一个

通过type属性可以配置

 这里我们拦截StatementHandler的query()方法

 拦截上面的query(Statement var1,ResultHandler var2)方法

上面代码args的值给错了,第二个参数应该是ResultHandler类型,在org.apache.ibatis.session.ResultHandler包下

 

 完整代码:

package com.lyx.mybatis.interceptors;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import java.sql.Statement;
import java.util.Properties;

@Intercepts({
        @Signature(type = StatementHandler.class,
                  method = "query",
                  args = {Statement.class, ResultHandler.class})
})
public class MyInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("这是一个拦截方法");
        Object proceed = invocation.proceed();
        System.out.println(proceed);
        return proceed;
    }
    //plugin()方法将拦截器中定义的增强功能和4大核心对象封装成一个整体
    @Override
    public Object plugin(Object o) {
        Object wrap = Plugin.wrap(o, this);
        return wrap;
    }
    //设置属性
    @Override
    public void setProperties(Properties properties) {
        System.out.println("设置属性"+properties);
    }
}

2.3 在mybatis-config.xml文件中配置<plugins>

 

 2.4 测试

 黑色方框中为intercept()方法的输出内容,由于我的queryStudentById()方法到数据库里面查了2次数据,查询Student,再通过Student的外键查classroom表,所以intercept()方法执行两次。并打印Object proceed;

刚刚plugin()方法没有打印信息,现在添加上,测试类改为UserTest,输出如下:可以看到plugin()方法执行了4次--->plugin()方法把拦截器和4大核心对象进行封装时会每一个都尝试封装一下

 3. 配置多个拦截器

 

 在mybatis-config.xml文件中配置:

测试 

 分析:

 编写多个拦截器时,执行顺序和<plugins>配置顺序一致

4. 拦截器的作用

例:

select * from student  拦截器 ➔ select * from student limit 3,5(例如分页插件)

select * from student  where Id = 1  拦截器 ➔ select * from student  where Id = 3

为MyInterceptor类的intercept()方法添加如下

Object target = invocation.getTarget();
System.out.println("目标对象"+target);

测试运行:

 看到target是RoutingStatementHandler类型

再添加代码:

MetaObject metaObject = SystemMetaObject.forObject(target);
metaObject.getValue("parameterHandler.parameterObject");

metaObject .getValue("xxx") 该方法可以获取RoutingStatementHandler 对象

从而通过RoutingStatementHandler.getBoundSql()获取到XxxMapper.xml中的sql:

metaObject.getValue("parameterHandler.boundsql.sql")

通过RoutingStatementHandler.getParameterHandler()取到XxxMapper.xml中的sql的参数值:

metaObject.getValue("parameterHandler.parameterObject");

 我们来获取一下queryUserById(12)方法的参数值:12

执行:

 

 由此,我们可以通过拦截器去修改这个参数值

5. 修改参数

5.1 写拦截器

添加注解

@Intercepts({

        @Signature(

                type =           ,

                method =         ,

                args = 

        )

})

 修改参数代码如下:

invocation.proceed();放行要最后写

 

 执行:

 改为11:

测试成功 

以上方法通过metaObject.setValue("parameterHandler.parameterObject",2);修改了参数

也可以通过metaObject.setValue("parameterHandler.boundSql.sql","select * from..");

完整MyInterceptor

package com.lyx.mybatis.interceptors;

import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.session.ResultHandler;

import java.sql.Statement;
import java.util.Properties;

@Intercepts({
        @Signature(type = StatementHandler.class,
                method = "parameterize",
                args = Statement.class)
})
public class MyInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object target = invocation.getTarget();
        MetaObject metaObject = SystemMetaObject.forObject(target);
        Object value = metaObject.getValue("parameterHandler.parameterObject");
        System.out.println("方法的参数值为:"+value);

        metaObject.setValue("parameterHandler.parameterObject",11);
        Object value2 = metaObject.getValue("parameterHandler.parameterObject");
        System.out.println("修改后方法的参数值为:"+value2);

        Object proceed = invocation.proceed();
        System.out.println(proceed);
        return proceed;
    }

    @Override
    public Object plugin(Object o) {
        Object wrap = Plugin.wrap(o, this);
        System.out.println("这是plugin : " + wrap);
        return wrap;
    }

    @Override
    public void setProperties(Properties properties) {
        System.out.println("这是设置属性" + properties);
    }
}

Mybatis源码解析七之-拦截器
a314773862的博客
07-15 425
介绍 Mybatis提供插件(plugin)功能,在实际中一般称为拦截器。 可以拦截的方法如下: Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed):拦截执行器的方法 ParameterHandler (getParameterObject, setPa...
自定义Mybatis拦截器 与PageHelper插件冲突问题
weixin_49294542的博客
04-28 1781
拦截器失效
Mybatis 自定义拦截器与插件开发
2301_82242844的博客
04-09 993
面试前的“练手”还是很重要的,所以开始面试之前一定要准备好啊,不然也是耽搁面试官和自己的时间。我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!面试前的“练手”还是很重要的,所以开始面试之前一定要准备好啊,不然也是耽搁面试官和自己的时间。
记录 有关mybatis拦截器
最新发布
zqx_7的博客
09-09 956
实现了InnerInterceptor类的类 可以用MybatisPlusInterceptor里的addInnerInterceptor()方法来把这个拦截器放进去,也可以自己写一个手动放进去。但是实现了Interceptor类的类不能用addInnerInterceptor()方法,用@Intercepts来自己写,实现一些拦截需求。
MyBatis-自定义Interceptor实战
xuedengyong的博客
09-14 763
1、编写自己的插件类 1)实现 Interceptor 接口 这个是所有的插件必须实现的接口。 2)添加@Intercepts({@Signature()}),指定拦截的对象和方法、方法参数 方法名称+参数类型,构成了方法的签名,决定了能够拦截到哪个方法。 问题:拦截签名跟参数的顺序有关系吗? 3)实现接口的 3 个方法 // 用于覆盖被拦截对象的原有方法(在调用代理对象 Plugin 的 invoke()方法时被调用) Obj...
MyBatis 拦截器 Interceptor 源码解析
谈谈1974
09-20 1581
文章目录1. MyBatis 拦截器 Interceptor 介绍2. Interceptor 实现源码分析2.1 拦截器 Interceptor 的注入2.2 拦截器 Interceptor 的应用2.3 拦截器 Interceptor 的生效 1. MyBatis 拦截器 Interceptor 介绍 MyBatis 提供了基于 Interceptor 的扩展机制,给使用方实现自定义逻辑留下了余地。笔者在 MyBatis @Intercepts 实现打印 SQL 语句 中介绍了拦截器的基本使用,实际
Mybatis拦截器Interceptor
wind_chasing_boy的博客
06-13 6615
最近项目使用Mybatis拦截器对数据进行加解密,以下记录如何将拦截器集成到项目中以及在使用过程中踩过的一些小坑,与君共勉Configuration:初始化基础配置,比如MyBatis的别名等,一些重要的类型对象,如插件,映射器,ObjectFactory和typeHandler对象,MyBatis所有的配置信息都维持在Configuration对象之中。SqlSessionFactory:SqlSession工厂。
mybatis拦截器interceptor源代码解析
bukebuhao的专栏
01-09 275
mybatis支持拦截器,实现的原理就是利用JDK的动态代理。先前利用拦截器实现了分页功能,如今又利用拦截器实现日志记录的功能,感觉拦截器还是不错的,只是相对于spring3 mvc的拦截器感觉有些逊色。接下来,我着重分析一些拦截的使用。 【基本思路】拦截器在哪里拦截?什么情况下才会拦截代理?怎么代理呢?只要搞清楚这些,基本的拦截器功能也就了如指掌啦。 拦截器在哪里呢?my...
Mybatis Plugin拦截器开发过程详解
08-25
Mybatis Plugin拦截器开发过程详解是Mybatis框架中的一种插件机制,允许开发者通过拦截器来拦截Mybatis的方法调用,从而实现自定义的逻辑处理。下面将详细介绍Mybatis Plugin拦截器的开发过程。 Mybatis Plugin拦截...
MyBatis拦截器分页与动态修改SQL及其参数值
10-09
1. **MyBatis拦截器**:MyBatis提供了一种插件机制,即拦截器Interceptor),它基于Java的动态代理,可以在SQL执行前或执行后进行干预。例如,我们可以创建一个自定义拦截器,来实现特定的功能,如日志记录、...
Mybatis Interceptor 拦截器的实现
08-26
Mybatis Interceptor 拦截器的实现 Mybatis Interceptor 拦截器的实现是 Mybatis 框架中的一种重要机制,通过拦截器可以改变 Mybatis 的默认行为,例如 SQL 重写等。拦截器的实现主要基于责任链模式,通过动态代理...
mybatis interceptor
06-06
mybatis实现分页的例子,为了记录下来以便于今后自己用。
mybatis拦截器
11-09
MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能。
MyBatis拦截器深度解析:关键功能与实战示例
MyBatis拦截器是其插件功能的核心部分,实际上是一种拦截器机制,允许开发者在MyBatis执行映射语句的过程中对关键操作进行自定义干预。MyBatis提供了丰富的拦截点,包括Executor接口的方法(如update、query、commit...
Mybatis自定义插件Interceptor
weixin_45549794的博客
10-10 924
**加粗 Mybatis自定义插件-Interceptor ** MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括: Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed) ParameterHandler (getParameterObject, setParameters) ResultSetHand
MyBatis 插件之拦截器Interceptor
chuixue24的博客
08-10 1551
一.背景 在很多业务场景下我们需要去拦截sql,达到不入侵原有代码业务处理一些东西,比如:分页操作,数据权限过滤操作,SQL执行时间性能监控等等,这里我们就可以用到Mybatis拦截器Interceptor 二.Mybatis核心对象介绍 从MyBatis代码实现的角度来看,MyBatis的主要的核心部件有以下几个: Configuration 初始化基础配置,比如MyBatis的别名等,一些重要的类型对象,如,插件,映射器,ObjectFactory和typeHandler对象,MyBati..
Mybatis自定义拦截器
2302_77659577的博客
08-10 1077
首先让我们来创建实现了Interceptor接口的自定义拦截器类.这里我们创建3个@Override// 拦截逻辑@Override// 动态代理@Override// 可以在这里设置配置属性@Override@Override@Override@Override@Override@OverrideMyBatis拦截器机制为我们提供了灵活的扩展方式,可以在SQL执行的不同阶段插入自定义逻辑。
MybatisPlus自定义拦截器修改sql
ChuanDD的博客
01-18 5245
mybatis plus自定义拦截器修改sql,直接拼接sql方式,预编译方式。springboot 使用mybatis plus拦截器自定义拦截器mybatis plus InnerInterceptor拦截器
自定义MyBatis拦截器
xzy的博客
02-07 8771
文章目录自定义MyBatis拦截器作用MyBatis中的四大核心对象在mybatis中可被拦截的类型有四种(按照拦截顺序)拦截器需要实现Mybatis提供的Interceptor接口利用反射获取运行中的实体字段的名字利用反射动态的为sql语句传递新参数使用mybatis自定义拦截器为插入,更新语句自动赋值的时候的小bug使用自定义MyBatis拦截器在对数据库进行更新插入的时候动态添加修改人,创建人参数定义拦截器类在mybatis的配置文件中声明拦截器在mapper映射文件中获取拦截器中设置的参数验证结果
写文章

热门文章

  • 安装Docker详细步骤总结 128259
  • HTML零基础入门教程完整版 27523
  • MobaXterm连接报错Network error: Connection timed out 25726
  • Linux下载安装MySql 22946
  • 分布式定时任务调度框架Quartz 22351

分类专栏

  • 微服务架构 19篇
  • 微信小程序 1篇
  • springboot 3篇
  • mysql 25篇
  • javaSE 9篇
  • Mybatis知识点 32篇
  • javaweb 32篇
  • jsp 2篇
  • servlet 12篇
  • 计算机网络 7篇
  • 报错 13篇
  • 高级框架 42篇
  • java 3篇
  • Spring(基础+进阶) 8篇
  • spring 7篇
  • ajax 1篇
  • jQuery 5篇
  • CRM 19篇
  • SQLyog 13篇
  • git 2篇
  • idea 5篇
  • jdbc 3篇
  • css 19篇
  • java基础面试题 1篇
  • maven 5篇
  • Nexus 1篇
  • SSM 1篇
  • bootstrap 2篇
  • 笔记 3篇
  • vue 1篇
  • 2058 1篇
  • 数据结构 1篇

最新评论

  • 安装Docker详细步骤总结

    2401_83981106: 写的太乱

  • Mybatis的XML映射文件中常用标签

    小小小勇: 虽然写的有点乱,但是还是很全面的,希望能整理一下格式

  • 安装Docker详细步骤总结

    lode金夏: 是不是提示不支持yum表情包

  • 安装Docker详细步骤总结

    手打柠檬茶。。: 第一个命令就安装失败了怎么办

  • Linux下载安装MySql

    weixin_42084008: 请问一下我第6步启动,时起不起来是什么原因呢?

最新文章

  • python遍历键值对kw.items()、 kw.keys()、 kw.values()、enumerate(kw.keys())
  • OA——菜单里无法找到流程监控
  • Python教程总结版
2024年1篇
2023年29篇
2022年220篇
2021年59篇
2020年30篇

目录

目录

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

素心如月桠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家贵溪玻璃钢牌匾雕塑出口玻璃钢花盆厂家直销庆阳人物玻璃钢雕塑安装汝城玻璃钢花盆花器贵州玻璃钢雕塑生产厂家彩绘玻璃钢雕塑厂家徐州卡通雕塑玻璃钢人物玻璃钢雕塑价格行情元古玻璃钢雕塑厂家景观玻璃钢雕塑专业公司福建玻璃钢卡通雕塑制作湖南附近玻璃钢卡通雕塑公司赣州玻璃钢雕塑工艺品放大玻璃钢雕塑漯河玻璃钢人物雕塑公司孝感玻璃钢卡通雕塑捕鱼雕塑多少钱玻璃钢虹口区知名玻璃钢雕塑来电咨询德宏玻璃钢雕塑代理玻璃钢工侠客雕塑淮安玻璃钢仿铜雕塑厂家供应自己晚上在家里做玻璃钢雕塑国外商场花艺美陈武汉怀化玻璃钢卡通雕塑商场美陈在哪里学习信阳玻璃钢雕塑设计潍坊玻璃钢雕塑定制佛山玻璃钢雕塑生成厂家商场玻璃顶吊饰美陈河南季节性商场美陈售价香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化