SpringMVC拦截器详解

来源:互联网 发布:对数据进行分段统计 编辑:程序博客网 时间:2024/06/05 04:39

拦截器是每个Web框架必备的功能,也是个老生常谈的主题了。

本文将分析SpringMVC的拦截器功能是如何设计的,让读者了解该功能设计的原理。

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

HandlerMapping的基础抽象类。

这里写图片描述

这里写图片描述

继承HandlerInterceptor的接口,额外提供了afterConcurrentHandlingStarted方法,该方法是用来处理异步请求。当Controller中有异步请求方法的时候会触发该方法。 楼主做过测试,异步请求先支持preHandle、然后执行afterConcurrentHandlingStarted。异步线程完成之后执行preHandle、postHandle、afterCompletion。 有兴趣的读者可自行研究。

这里写图片描述

这里写图片描述

实现AsyncHandlerInterceptor接口的抽象类,一般我们使用拦截器的话都会继承这个类。然后复写相应的方法。

这里写图片描述

这里写图片描述

首先我们看下拦截器的如何被调用的。

Web请求被DispatcherServlet截获后,会调用DispatcherServlet的doDispatcher方法。

这里写图片描述

这里写图片描述

很明显地看到,在HandlerAdapter处理之后,以及处理完成之后会调用HandlerExecutionChain的方法。

HandlerExecutionChain的applyPreHandle、applyPostHandle、triggerAfterCompletion方法如下:

这里写图片描述

这里写图片描述

这里写图片描述

很明显,就是调用内部实现HandlerInterceptor该接口集合的各个对应方法。

下面我们看下HandlerExecutionChain的构造过程。

HandlerExecutionChain是从HandlerMapping接口的getHandler方法获取的。

HandlerMapping的基础抽象类AbstractHandlerMapping中:
这里写图片描述

这里写图片描述

我们看到,HandlerExecutionChain的拦截器是从AbstractHandlerMapping中的adaptedInterceptors属性中获取的。

这里写图片描述

清楚了HandlerExecutionChain的拦截器属性如何构造之后,下面来看下SpringMVC是如何配置拦截器的。

  1. *-dispatcher.xml配置文件中添加 配置
<mvc:interceptors>  <mvc:interceptor>    <mvc:mapping path="/**"/>    <mvc:exclude-mapping path="/login"/>       <mvc:exclude-mapping path="/index"/>    <bean class="package.interceptor.XXInterceptor"/>  </mvc:interceptor></mvc:interceptors>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这里配置的每个<mvc:interceptor>都会被解析成MappedInterceptor。

其中子标签<mvc:mapping path="/**"/>会被解析成MappedInterceptorincludePatterns属性;<mvc:exclude-mapping path="/**"/>会被解析成MappedInterceptorexcludePatterns属性;<bean/>会被解析成MappedInterceptor的interceptor属性。

<mvc:interceptors>这个标签是被InterceptorsBeanDefinitionParser类解析。