2023-09-14  阅读(1)
原文作者:王伟王胖胖 原文地址: https://blog.csdn.net/wangwei19871103/article/details/105556222

执行链结构图

202309142302544441.png

拦截器哪里来的

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

202309142302550322.png

202309142302565273.png

这些拦截器干嘛的

MyHandlerInterceptor自定义的

只是输出信息。

202309142302571144.png

ConversionServiceExposingInterceptor

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

202309142302587275.png

ResourceUrlProviderExposingInterceptor

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

202309142302594346.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);
    				}
    			}
    		}
    	}

好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文