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
等操作。
既完成了任务又巩固了原来的知识,这种感觉很棒,最关键的是还有钱拿……
本文代码
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。