00:00
好,那么基于之前的原理呢,我们来看一下我们要完成一个插件怎么做。我们来说一下这个插件的编写步骤,插件咱们这个编写首先呢,我们知道了一件事,就是呢,我们这个插件呢,会来包装我们每一个对象的创建过程,所以说呢,我们插件第一步来我们所谓的这个intercept,就是我们插件点进去来,这是我们啊规定的一个intercept接口,这个接口就是我们插件要实现的接口。第一个我们要编写咱们这intercept的实现类,这个就是我们所谓的插件,然后呢,我们在这里边我们来编写一个。好,我们就叫my first。Plugin。好,然后呢,我们来让它实现,诶,实现我们的intercept接口。
01:03
好看好啊,是我们I贝利in好添加未实现的方法,我们就来看一下这些未实现的方法,第一个方法呢,翻译过来叫intercept,哎,Intercept呢,它意思叫拦截的意思。它呢,就是拦截目标方法执行的。的执行啊,拦截目标对象的目标方法,要说呢,你拦截是四大对象,哪个对象的哪个方法拦截这些方法的执行,而在执行过程中呢,我们看会有一个invocation,这个invocation呢,是我们AB里边的一个VOC,它有一个方法,第二第那么这一块呢,有一个叫proceed,哎,就是处理,这个处理呢会有一个返回值,这个返回值哎这一块就相当于我们这个放行执行目标方法,比如说呢,我们只要显示的调用了一个invocation proceed,咱们只要目标方法就会被执行,执行后的返回值我们应该也返回出来。
02:12
返回执行后的返回值。接下来呢,我们来看第二个方法。第二个方法呢,它叫plug plug呢翻译过来,哎,这就是啊,我们要开始查件包装了,为什么呢?我们来看啊,每一个intercept对象都会在四大对象创建的时候,你看啊,拿到所有intercept,然后呢,每一个intercept调用它的plug,这个plug方法就是来包装我们这个目标对象的。包装目标对象,而我们所谓的这个包装,其实就是为目标对象创建一个。咱们这个代理项好,那么接下来呢,我们就可以在这,哎你可以呢,利用proxy之类的,哎,Proxy来写这些,你为他创建一个代理对象,但是呢,因为这个马贝斯也考虑到你经常要创建代理对象了,他呢有一个非常简单的方法,马贝蒂斯提供了一个类叫plugin,就是这个类,这个类里边呢,呃,定义了一个咱们这个方法就叫wap,哎包装,然后呢,把你要包装的目标对象传进来,用哪个拦截器包装,哎,就是我们当前的拦截器,哎,我们传进来就会给我们返回一个包装后的对象。
03:43
哎,也就是说呢,马贝蒂斯,为了我们使用方便啊,我们我们可以借助这个类,大家也可以自己写啊,我们可以诶借助。借助plug类的,咱们这个方法。Map方法来使用当前拦截器,当前咱们这个intercept,使用当前的咱们这个intercept拦截。
04:09
包装我们目标对象好,所以说呢,这一块返回的就是包装后的对象,也就是创建好的动态代理返回啊,为当前他给他创建的动态代理。动态代理这个挖方法呢,大家可以点进去看一下,哎,非常简单啊,就是说呢,Target拿过来,嗯,Target的类型拿过来,以及这个类型要实现的接口拿过来,你看啊,就是调用proy new pro instance来来给我们创建出来这个代理对象的,好所以说呢,我们这一块呢,哎,创建出了一个代理,动态代理,接下来还有一个方法。叫set properties,这个set properties呢,哎,它的作用是将咱们这个插件。
05:08
将咱们这个插件注册时时。咱们这些property。属性属性,哎设置进来,哎这块呢,就会有一个properties,你用这个properties就能拿到,哎咱们这个插件,嗯,配置的。信息信息。好。这就是这三个方法的作用,哎,我们大概的也写了一下,那么接下来你把这个写完,那肯定是不够的,因为我们知道它是,哎,Intercept能拦截每一个对象的每一个方法,所以说呢,你接下来就得来具体的告诉我们贝,你这个插件到底是用来拦截哪个对象的哪个方法的,否则这一块运行起来就是不行的。好,我们接下来使用一个注解,就叫注解叫intercepts,诶这个intercepts呢,就叫拦截,点进去这个注解里边呢,能写一个S注解的这个这个属性。
06:20
好,我们接下来写上它。它里边哎,有一个single nature数组,哎,数组呢,我就用大括号表示,数组里边呢,每一个都是一个single nature,而这个single nature怎么写呢?我们点进去有三个东西,一个叫type method a type指的就是你要拦截哪个对象来,四大对象指哪个对象,Method指定你拦截这个对象的哪个方法,而二就是指定当前方法的参数列表,因为有可能有些方法会写一个重载的方法,比如都是quary方法,有一个带了三个参数,有一个带了四个参数,有一个带了五个参数,我们就是通过二标识来告诉你是哪个方法,好们就来写一个type type呢,我们以statement handle为例,好,我们就来拦截statement看到了。
07:17
好,我们拦截这个对象,那么接下来我们来说一下拦截这个对象的哪个方法呢?我们来指定method method使用method指定你要拦截哪个方法,我们进入statement statement呢,哎,调用有这么多的方法啊,比如叫prepare,哎,Preter rise,哎这一块呢,就是参数,咱们circle预编译,这就是设置参数,比如我可以拦截这个,哎,设置参数的方法。哎,我们来可以写在这。好,你要拦截哪个方法,把方法名用说啊传进来,接下来呢,还有一个当前方法用的参数X,好,我们来看一下咱们这个statement。
08:05
看到了。那规定的这个primemeter rise方法的,咱们这个用的参数就是我们这个statement对象,哎,把这个statement。全里面拿过来。好。在这儿。我们来写好这个方法的参数呢,就是它。点好写一个它这样的话呢,我们通过这个注解,相当于完成了插件的签名。嗯,完成咱们这个插件签名,插件签名的目的来就是来告诉马贝蒂斯当前插件用来拦截哪个对象的哪个方法。当前咱们这个插件用来拦截哪个对象的,哪个方法好,那么呢,我们这一块相当于我们两步,第一步实现完这个接口,第二步使用这个注解完成插件签名。
09:08
第二,使用inter注解。完成咱们这个插件签名。来,我来拦截哪个对象的哪个方法,接下来第三步,插件写好,你放在这,MY是不知道的,你一定要注册在全局配置文件中。将咱们这个写好的插件注册到全局。全局配置文件中。好,我们来来到MY全局配置文件,诶我们之前呢讲过这一块呢,有一个标签叫咱们这个plugins,哎,这个标签就是使用这个标签来注册插插件。
10:02
注册它是用来注册插件的,它怎么注册呢?哎,每一个插件就用plug标签,Intercept,就是咱们这个插件的全类名拿过来。好。放在这好,这是我们插件的全类名,接下来呢,你如果定义插件的时候,你也可以给插件传一些KY6,你自定义一些,比如呢,我们传一个username,哎,然后呢,我们叫root或传一个password。PASSWORD123456,哎,我随便传一些东西,你传的这些KY6就会,哎,利用插件的这个set properties,把这些插件传到QY,就会包装成一个properties,方便呢,你在程序运行期间可以用的那些属性,好,我们这个插件就写好了这么几步,第一步呢,我们实现了这个接口。第二步我们完成插件签名,第三步注册,接下来我们就可以测试一下我们这个插件,这个插件呢,我们每每一步我们都打印一下。
11:09
好,这是my first。Intercept方法。而这个intercept方法呢,我们可以拿到通过这个vocation对象,拿到它要拦截的咱们这个点get,哎,它要拦截的这个目标方法。好,接下来呢,我们可以在这一块我们也来打印。这个呢,是咱们my first。Plug方法,这个plug方法呢,我们都知道,在四大对象创建的时候要被调用好,我们plug的对象,我们来打印过来,哎,这个呢,就是我们马贝蒂斯。包装的咱们这个对象。将要。包装的对象好,然后呢,我们这个set properties好,我们放在这,我们来运行一下。
12:11
好,我们随便拿一个方法运行啊,我来测试。我们让他启动查询之前呢,我们来看我们这个插件的流程,诶,我们来看插件的配置信息,哎,我们写的那些KY6,哎,会被呢打印出来,哎,能拿得到我们四大对象,因为查询要创建四大对象创建的时候呢,插件也就初始化好了,哎,这些信息都能被拿到,大家来看啊,插件呢会拦截每一个对象,比如呢,刚要创建一个,呃,咱们ex了,要创建handle了,Set handle了和statement handle来,每个对象要创建都会调用这个。Plug方法,哎,调用这个方法,而这个方法真正的能不能包装我们这个对象,我们可以来看一下,一会来看一下源码啊,而当我们正要来执行增删改查的时候,你看他要拦截的方法。
13:09
它要拦截哎我们statement的,哎,Rise方法,哎要拦截这个方法,所以说呢,我们要S语句句编译以后,我们要设置参数,哎设置参数之前就会被插件的引物,哎,Intercept方法所拦截,然后呢,哎,咱们这个插件就运行完了,也就说呢,我们这个inter能在我们目标方法执行之前拦截,而至于这个plug到底包装出来长啥样。好,Debug运行。好,我们来看啊。我们来到咱们这个测试类里边,好调用咱们这个要包装的对象,当前呢是咱们堪称我们来看它包装了没有。走调用这个wap方法,拿到咱们这个相当于当前插件的签名,诶这个签名里边呢,就有我们这个插件,它拦截哪些对象的哪些方法,你看啊,拦截statementment handle了prime的这个方法,哎,然后呢,拿拿到我们这个类型,目目标对象的类型,我们的拿到它的接口,但是呢,我们来看啊,它在调用返回proxy new的时候,它有一个判断,先拿到interface,也就是说看一下我们当前的这个啊,这个类型是不是在我们插件签名里边,而我们插件签名呢,只是告诉我们要拦截statement的对象,哎,如果没有,你看啊,如果在里边才返回代理对象没在,直接就把目标对象返回了,所以说其他不相关的对象,哎,Ex这类的啊,我们直接返回。
14:52
哎,直接返回,而接下来呢,接下来我们再来看。又是第二个,第二个呢,我们接下来第三个,哎,你看啊,它就是直接返回了。
15:06
它直接返回了,我们继续放行,放行呢,接下来再来进入啊,我们permit handler的咱们这个,呃,咱们这个创建了啊,我们要拦截的是什么呢?我们来进去,我们来看啊,我们这个插件要拦截的是statement看到了。所以说呢,我们这个permit看到了,你看我们这个插件签名,签名呢,它要拦截statement看到了,所以说呢,跟它不相关的permit看到了,也会被放行,不会拦截,诶不会创建这个代理对象,好直接就放好,我们继续往下走,接下来呢,Result set看到了,我们也放了,好整个呢,最后一个咱们这个statement看到了,诶我给放过了。来,放上几次好次,两次三次,好,接下来呢,我们来进来。好,进来我们来看啊,现在呢,Target给他目标类型就是我们statement handle了,而这个statement handle了呢,就在我们差件签名里边,我们就是要拦它的,所以说呢,这个interface,哎,我们从插件签名里边获取这个接口的interface,诶会有值,有值以后呢,我们就会为这个哎目标对象创建出代理对象走。
16:21
诶,创建一个代理对象,当调用plug wa包装成功以后,这个对象,哎,我们来看就是这样子的。看啊,我们这里呢,包装的对象。这是我们当前插件啊,My first plug,而当前插件里边呢,有一个target,这个target才是目标对象,哎,比如说呢,我们这个代理对象里边,这是我们第一个插件my first plug,哎,Target里边的target才是我们的啊routine sta看到了啊,也就是说呢,这是我们的STEM看到了。被插件一包装以后呢。
17:03
哎,这个截图大家记住就行了,差价差价。差价会产生代理,呃,产生目标对象啊,咱们这个代理对象,哎,我们看到了确实是statement handleler的代理对象,哎就产生出了这个PROXY7了,把这个代理对象呢,最终是返回给myab,让他用叉了,这样的话呢,Myab,哎每次要执行增删改查,你看啊,我们这个statement handle最终返回的就是这个代理对象。哎,我们把它拿到。大家看一下哎,它里边的target才是真正的对象,而我们是当前用my first plug拦截的。好,所以说呢,这就是插件包装了某个对象后的效果,那么接下来你要执行statement,哎,要进行预编译了,我们可以进去返回进去进去看,好啊,我们这个handle了,调用prepare方法了,哎,那当然也是调用咱们这个插件的prepare,哎,接下来关键是参数预编译了,这个预编译的话,因为我们是代理对象,所以说呢,我们来step into会直接来到我们这个plug里边,哎,会执行代理对象的咱们这个in work方法,而这个work方法呢,就是帮我们,哎先来执行intercept的intercept辅导方法,就说呢,把我们这个插件的INTERCEPT1执行,把插件的执行后的返回值交给我们,所以说真正的啊,目标方法的执行是我们差价这一块在执行,如果你这一块直接都不掉,目标方法也就。
18:52
不执行了,所以说呢,这一块大家一定注意,这就是我们这个插件的这个流程,这个流程呢,我们打印的这些内容,哎大家看好,哎配置信息也能拿到我们启动的时候呢,哎要包装的这个statement对象,我们最终会给它产生动态代理,而我们咱们这个设置参数的这个方法,我们最终都是哎调用咱们这个插件。
19:19
的,咱们这个inter方法完成的好,这就是插件利用动态代理在这一块拦截了目标方法的执行,我们只有调用proceed了,我们四大对象真正的方法才会被执行,我要不调了这一块就不能被执行,我们就可以在目标方法执行的时候,我们在这一块做一些更改,比如呢,我拿到当前方法,我把它要用的参数改一改,把这些都改完以后,我再让他执行,这就达到我们可以介入到马贝蒂斯内部流程,哎,这个插件呢,开发的时候特别要小心,因为它一不小心就会破坏到马贝蒂斯的底层。
我来说两句