拦截器

2023-06-30  本文已影响0人  程序员札记

执行链结构图

image.png

拦截器哪里来的

执行链前面讲过,但是没细讲,我们先来看他是怎么形成的。首先是在EnableWebMvcConfiguration的父类WebMvcConfigurationSupportgetInterceptors里面会添加自定义的拦截器,然后再加入两个拦截器:

image.png
image.png

这些拦截器干嘛的

MyHandlerInterceptor自定义的

只是输出信息。


image.png

ConversionServiceExposingInterceptor

设置请求的转换服务,这个后面跟数据绑定相关,到时候会说的。

image.png

ResourceUrlProviderExposingInterceptor

设置静态资源url提供器,让客户端可以访问静态资源。

image.png

拦截器处理

遍历所有的拦截器,进行preHandle调用,如果返回true就继续并执行的拦截器索引,否则就直接后处理返回了,这里interceptorIndex是为了后面的处理可以反向进行遍历,其实就是类似于netty的出站入站处理,有兴趣的可以看看我的netty文章,数据进来的时候是顺序拦截,出去的时候是反的拦截,类似责任链,拦截器模式。

applyPreHandle

    boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HandlerInterceptor[] interceptors = getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for (int i = 0; i < interceptors.length; i++) {
                HandlerInterceptor interceptor = interceptors[i];
                if (!interceptor.preHandle(request, response, this.handler)) {
                    triggerAfterCompletion(request, response, null);//如果是false就直接返回
                    return false;
                }
                this.interceptorIndex = i;
            }
        }
        return true;
    }

applyPostHandle

这里就开始反向拦截了。

    void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)
            throws Exception {

        HandlerInterceptor[] interceptors = getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for (int i = interceptors.length - 1; i >= 0; i--) {
                HandlerInterceptor interceptor = interceptors[i];
                interceptor.postHandle(request, response, this.handler, mv);
            }
        }
    }

triggerAfterCompletion

处理完成后进行,这里就要用到interceptorIndex,反向执行,因为有可能有拦截器返回false了,然后只处理前面处理过的拦截器的triggerAfterCompletion方法。

void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)
            throws Exception {

        HandlerInterceptor[] interceptors = getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for (int i = this.interceptorIndex; i >= 0; i--) {
                HandlerInterceptor interceptor = interceptors[i];
                try {
                    interceptor.afterCompletion(request, response, this.handler, ex);
                }
                catch (Throwable ex2) {
                    logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
                }
            }
        }
    }

上一篇 下一篇

猜你喜欢

热点阅读