拦截器
拦截器作用的位置
客户端发送一个请求,首先是经过过滤器Fitter来进行处理,过滤器通过后就交给DispatherServlet来处理,然后DispatherServlet就会找到控制层中对应的控制方法,就是xxxhandler,而拦截器的作用位置就是DispatherServlet和xxxhandler之间的一层
简介
Spring MVC也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义的拦截器可以实现HandlerInterceptor接口,也可以继承HandlerInterceptorAdapter 适配器类
接口里面有三个方法:
每个方法的作用位置
结合原码也可以发现他们的作用位置
自定义拦截方式
多个拦截器的执行顺序(原码分析)
首先是debug进行跟踪查看
从debug界面可以看出,
Handler execution chain, consisting of handler object and any handler interceptors.Returned by HandlerMapping’s HandlerMapping.getHandler method.
mappedHandler是一个执行处理器,包含处理对象(就是控制层的每一个RequestMapping)和拦截器,而且可以看出拦截器是用一个ArrayList来存储
Interface to be implemented by objects that define a mapping betweenrequests and handler objects.
这个接口就是被定义在请求和对象之间的对象实现,就是处理器吧
这个是拦截前的方法
如果返回的是false,表示拦截,就会进到方法里面,直接结束这个方法
如果返回true,代表的是拦截器放行,所以就不会进到这个if里面
进入applyPreHandle
会先判断getInterceptors数组里面有没有拦截器
数组有拦截器就对数组进行遍历拦截器,然后取出来拦截器进行执行
执行先调用你重写的preHandle方法
如果返回false,就是拦截的话,就会进入if里面,调用triggerAfterCompletion方法就结束,具体的triggerAfterCompletion方法干什么后面描述
如果返回的是true,那么就会this.interceptorIndex = i;就没了
然后我们得了解一下interceptorIndex的意思,后面描述
PreHandle执行完了,现在到PostHandle
进入applyPostHandle发现它是从数组后面进行遍历的
现在到AfterCompletion
进入triggerAfterCompletion,也是从后面进行遍历的
经过上面,我们还有两个疑惑,就是triggerAfterCompletion方法的作用和interceptorIndex的作用是干嘛的,因为这两个东西都是返回false才会执行的和使用的,所以我们将第二个改成返回false,第一个还是返回true现在interceptorIndex是1,我们遍历到第二个拦截器了,进入到triggerAfterCompletion里面看看
triggerAfterCompletion就是调用AfterCompletion,而且是将interceptorIndex之前的拦截器的afterCompletion都执行