MyBatis功能点之二(2):从责任链设计模式的角度理解插件实现技术

  MyBatis允许对其四大组件(Executor,StatementHandler,ParameterHandler, ResultSetHandler)进行增强处理。在创建四大组件对象的时候

    1、每个对象创建处理都不是直接返回,而是使用拦截器链拦截处理(interceptorChain.pluginAll(四大对象))

    2、获取到所有的interceptor(可自定义或第三方提供到的接口),调用interceptor.plugin(targent),返回包装后的target对象

  参考https://www.cnblogs.com/ilovebath/p/14510697.html中末尾部分。

  那么自定义或者第三方提供的插件,是如何被MyBatists组拦截链(责任链模式)并被拦截,同时增加四大组件中要被增强的方法的?所有插件均需实现Interceptor接口,同时声明该interceptor对四大组件的哪个部分作用。

一、生成插件责任链

      

   在https://www.cnblogs.com/ilovebath/p/14597340.html——MyBatis插件的使用案例中,通过配合<plugin>标签,使插件可使用。MyBatis解析sqlMapConfig.xml的时候如上图所示生成有效的拦截器链保存在对象Configuration的InterceptorChain类中。

  跟踪源码,可知拦截器链本质插件数据列表,如下图:

      

二、拦截插件责任链

   1、生成拦截器链图中,在解析xml文件时setProperties就会生效。

   2、通过调试信息(如下),遇到了之前讲解Cache时熟悉的对象Executor。

      

   opensession执行过程中,对于Executor根据类型不同实例化后,对executor对象进行如下操作:

      

        

  此为Executor的Interceptor包装,此后调用invoke方法将对组件进行包装,如下:

      

   此方法将target(即MyBatis四大组件对象之一)通过拦截器链层层wrap之后返回

      

三、方法增强(jdk动态代理)

  测试案例中带增强的方式是prepare,跟踪至prepare的执行过程:

       

   即Plugin类实例作用,查看Plugin类源码可知其implements InvocationHandler。

      

   即执行prepare时生成代理对象,增强功能:

      

posted on 2021-03-09 15:36  池塘里洗澡的鸭子  阅读(110)  评论(0编辑  收藏  举报