Mybatis中拦截器的简单实现方法
前言
需求驱动学习,最近一周组长让我在业务模块里加日志,经过与导师以及组长讨论决定用拦截器记录日志。周五下班前已经发了提测邮件。
虽然我知道MyBatis有这东西,但是没在实际情况中用过,心里有点虚2333……所以才有了此文的理解。
前世今生
它的本质就是JDK的动态代理。首先先来复习一下动态代理我贴了一段最常见的JDK动态代理的代码
//服务员的接口 publicinterfaceWaiter{ voidserve(); } //服务员的实现 publicclassWaiterImplimplementsWaiter{ @Override publicvoidserve(){ System.out.println("服务中..."); } } //需要代理的对象处理器 classWaitInvocationHandlerimplementsInvocationHandler{ privateWaiterwaiter; publicWaitInvocationHandler(Waiterwaiter1){ waiter=waiter1; } @Override publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{ System.out.println("你好"); Objectinvoke=method.invoke(waiter,args); System.out.println("再见"); returninvoke; } } publicclassApp{ //普通的实现 @Test publicvoidfun(){ Waiterwaiter=newWaiterImpl(); waiter.serve(); } @Test publicvoidfun1(){ Waitera=newWaiterImpl(); ClassLoaderclassLoader=getClass().getClassLoader(); Class[]classes={Waiter.class}; //生成代理对象 Waiterwaiterproxy=(Waiter)Proxy.newProxyInstance(classLoader,classes,newWaitInvocationHandler(a)); waiterproxy.serve(); } }
拦截器
V1
我现在要在函数执行前后记录日志操作,考虑需要在代理方法那里定义个拦截器的接口,如下代码所示
//拦截器V1版本 publicinterfaceMyInterceptorV1{ voidinterceptor(); } //代理对象变成这个 publicclassTargetProxyV1implementsInvocationHandler{ privateTargettarget; privateMyInterceptorV1myInterceptor; publicTargetProxyV1(Targettarget,MyInterceptorV1myInterceptor){ this.target=target; this.myInterceptor=myInterceptor; } @Override publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{ myInterceptor.interceptor(); returnmethod.invoke(target,args); } }
这是最简单的版本,但是我们很多时候需要拦截参数等根据参数判断拦不拦截等,代码更新如下
publicinterfaceMyInterceptorV1{ voidinterceptor(Methodmethod,Object[]args); } @Override publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{ myInterceptor.interceptor(method,args); returnmethod.invoke(target,args); }
V2
似乎上面的方案很完美
废话肯定不完美,不然怎么会有这段
没错,第二段代码并不是很优雅,有方法参数重复,可以考虑将三者抽出来,直接在拦截器的实现里写上method.invoke(target,args);,如下代码所示
@Getter @Setter @AllArgsConstructor publicclassMyInvocation{ privateObjecttarget; privateMethodmethod; privateObject[]args; publicObjectproceed()throwsInvocationTargetException,IllegalAccessException{ returnmethod.invoke(target,args); } } //没错这就是V2版本 publicinterfaceMyInterceptorV2{ Objectinterceptor(MyInvocationinvocation)throwsThrowable; }
总结
Mybatis的拦截器就是像我上面这么写的,
名字也跟我取得一样,只是它更加复杂,能够通过注解区分拦截update操作和query
等操作。
既完成了任务又巩固了原来的知识,这种感觉很棒,最关键的是还有钱拿……
本文代码
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。