Mybatis插件原理

单个插件的拦截原理

	1.mybatis的Invocationhandler是 Plugin类
	2.interceptor接口里面有三个方法
		1.plugin():根据@signature创建代理类对象,没有被标识的四大对象,直接返回,不返回代理对象
		  Plugin.wrap(target,interceptot)这是Mybatis提供的简化操作,底层也是调用Proxy.newProxyInstance创建代理对象
		  
		2.serProperties():可以给interceptor设置一些properties,在全局配置文件注册plugin的时候,可以设置
		
		3.重点:intercept()这是最后执行aop目标方法的地方
		  里面调用invocation.proceed()执行目标方法,在前后可以完成aop
		  但是这并不是invocationHandler的invoke方法,invoke方法会执行interceptor的intercept方法,进入这个方法最终执行
		  
	3.在 interceptor实现类上有一个注解,@Intercept({@Signature(
	type = 拦截哪个四大对象,method  = 四大对象的哪个方法,args=)})
	
	4.在全局配置文件中注册 intercept插件

单个插件的拦截原理(具体执行过程)

	1.四大对象在创建时,就执行了interceptor的plugin方法,创建出了代理类对象
	(当然,plugin方法里面创建代理类对象的具体实现,要我们手动填写)
	2.有了代理对象,那么proxy在执行方法时,就会进入 invocationHandler的 invoke方法
	  so,mybatis的InvocationHandler是谁?
	  是Plugin类(Mybatis包下的一个类)
	3.Plugin类的invoke方法,会调用 interceptor的 intercept方法
	  this is why 最终执行目标方法aop,在interceptor的intercept方法里面

多个插件的原理(拦截器链)

	1.按顺序注册插件
	
	2.按顺序,四大对象创建后,都会调用 interceptorChains 中的 interceptor
	去调用它的,plugin方法,去生成代理对象(根据 signature)
	
	3.原理是,第一个 interceptor 生成的 proxy,会直接作为 target 返回给 下一个
	interceptor,去调用 plugin方法,生成下一个代理对象
	so,最终的 proxy,是按注册顺序一层一层包装的 proxy,proxy里面的 需要被代理的对象的类型就是proxy
	
	4.proxy生成后,执行invoke,里面的 interceptor.intercept(invocation)的时候是,
	会调用invocation.proceed(),这个就是proxy里面的真正的对象去执行它的方法,
	但是这个真正的对象,也是proxy,就会重复上面这个操作
	所以,proxy最后执行的时候,是按注册的反顺序执行的 intercept()方法,
	最后只剩下 真正对象了,才会执行真正对象的目标方法
	
	5.结论:生成代理对象是按注册顺序,执行目标方法是按 相反的 注册顺序

拦截器底层就是aop和责任链模式,那么是aop,就要有代理对象,和invocationHandler,另外拦截器必须得有 标识(拦截哪些对象的哪些方法)

2.责任链模式:事件对象(四大对象),责任链(interceptorChain,里面组织处理器的顺序的用的list实现的),四大对象被创建后,传给责任链,责任链的每个处理器按顺序调用handler(事件对象)方法,针对mybatis是如何实现这个handler方法的,mybatis是里面的interceptor,的plugin方法,其主要目的生成代理对象,因为拦截器后面用的就是动态代理模式,但是这个跟 责任链模式无关。ok,那么处理器的处理条件是什么?就是interceptor的@signature(哪个对象,方法),当四大对象进来interceptor的plugin方法后,判断这个对象的这个方法是否存在,存在那么,给这个对象的(这个接口方法)生成对应的 proxy,如果没有,那么处理器将这个事件对象传给下一个处理器处理

3.拦截器如果不注册,那么mybatis源码中的走interceptorchain,不会处理事件对象,返回的还是原 事件对象

4.当处理器链执行完,返回了对应的proxy,当proxy在执行方法的时候,就会进入invocationHandler的invoke方法,这里就是动态代理,前面处理 事件对象的过程是责任链模式,但是invoke方法不会直接执行具体的动态代理增强,它会 将proxy的内容,封装成一个invocation,传给当前的interceptor的intercept(invocation)方法,在这个方法里面做增强

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值