阅读HandlerInterceptor接口源码的理解
一、阅读接口类注释
我先理解的方法,方法都看懂了类注释自然而然明白了。所以此处略。
二、阅读preHandle()方法注释
Intercept the execution of a handler. Called after HandlerMapping determined an appropriate handler object, but before HandlerAdapter invokes the handler.
理解:拦截一个handler处理器的执行。这个方法的调用时机:在映射处理器(HandlerMapping)指定合适的处理器对象之后,处理器适配器(HandlerAdapter)调用处理器之前。
DispatcherServlet processes a handler in an execution chain, consisting of any number of interceptors, with the handler itself at the end. With this method, each interceptor can decide to abort the execution chain, typically sending a HTTP error or writing a custom response.
理解:前端控制器调用一个处理器在一个执行链中(也就是说处理器和拦截器组成了一个执行链条),这个执行链条可以有任意个拦截器,但是handler(处理器)在这个执行链条的最后,即,先执行链条中的所有拦截器才执行处理器。通过这个方法,每一个拦截器都可以决定是否可以终止这个执行链条,通常发送一个HTTP错误或者一个自定义一个响应。
注意:special considerations apply for asynchronous request processing. For more details see {@link org.springframework.web.servlet.AsyncHandlerInterceptor}.
三、阅读postHandle()方法注释
Intercept the execution of a handler. Called after HandlerAdapter actually invoked the handler, but before the DispatcherServlet renders the view.
理解:拦截一个处理的执行。这个方法的调用时机是:在处理器适配器调用处理器之后,但前端控制器渲染视图之前。
Can expose additional model objects to the view via the given ModelAndView.
理解:可以通过给定的 ModelAndView 对象,暴露额外的模型对象给视图。
DispatcherServlet processes a handler in an execution chain, consisting of any number of interceptors, with the handler itself at the end. With this method, each interceptor can post-process an execution, getting applied in inverse order of the execution chain.
理解:前端控制器调用的处理器在一个执行链中,这个执行链由许多拦截器组成,并且处理器在执行链的最后。通过这个方法,每个拦截器都可以后处理一个执行任务,这个执行链中每个拦截器的postHandle()方法的执行顺序是逆序的。也就是跟preHandle()方法的执行顺序是相反的。看下面的图更好理解。
四、阅读afterCompletion()方法注释
Callback after completion of request processing, that is, after rendering the view. Will be called on any outcome of handler execution, thus allows for proper resource cleanup. Note: Will only be called if this interceptor's {@code preHandle} method has successfully completed and returned {@code true}!
理解:这个方法在请求处理完成之后回调,也就是说,它的调用是在渲染视图之后调用。它将会在处理器执行完,不管是得到任何结果的时候都会调用,因此可以用它释放资源。但是需要注意的是:它执行的前提条件是它所处的拦截器的preHandle()方法要成功执行完并且返回true的时候才会被执行。
五、总结:
每一个拦截器都有一个preHandle()方法和postHandle()方法。在调用处理器之前后,都会调用拦截器。由许多个拦截器组成一个执行链,而这个执行链是以数组的形式存在。所以,执行这个执行链的中的所有拦截器的preHandle()方法是按照interceptor[]数组的正序执行的,也就是按数组下标从小到大执行每一个拦截器的preHandle()方法。而拦截器的postHandle()方法的执行是按照逆序执行的,也就是按照interceptor[]数组的下标从大到小的顺序执行拦截器中的postHandle()方法。而拦截器中的每一个afterCompletion()方法都是在渲染完视图以后按照interceptor[]数组的下标从大到小的顺序执行拦截器中的afterCompletion()方法,也就是说afterCompletion()方法的执行顺序跟postHandle()方法的执行顺序是一样的。说这么多还不如一张图。如下图:
以上是正常情况下的执行顺序,但是:当某一个拦截器的preHandle()方法()返回false,那么handler(处理器就不会执行)。它会直接去掉用当前拦截器的前一个拦截器的afterCompletion()方法,从这个方法开始逆序执行。比如:这里的interceptor3的preHandle()方法返回false。那么就会直接调用interceptor2的afterCompletion()方法,并从这个方法开始逆序执行至结束。