springMVC-Interceptor-源码分析

本文主要记录本身学习过程,若有错误请指出

一.用法

1.常引用拦截器 : HandlerInterceptor

代码以下:web

本身实现的拦截器
上图代码中 myMyHandlerInterceptor 注意:

  1. 实现HandlerInterceptor接口
  2. @Component 注解

如今spring-ioc 容器中已经存在我本身建立的拦截器,可是还要把它WebMvcConfigurationSupport(后面会讲为啥要交给它管理)spring

代码以下:spring-mvc

要完成对拦截器的使用,上图代码中注意两点:

  1. 重写 addInterceptors 方法
  2. @Configuration

上述作法以后可使用 拦截器了

二.源码

看源码 逆向思惟 -> 拦截器在哪里执行的 -> 拦截器是哪里来的

1.拦截在哪里执行的

  1. 我看到网上有不少说拦截器的实现原理是动态代理,其实并非, aop的实现原理是动态代理
  2. 拦截器的实现原理是执行链 HandlerExecutionChain
  3. 这个过程是HandlerExecutionChain是spring-mvc(由于这个文章记录的是拦截器,不会多说springmvc的东西) 中产生的.

执行代码以下: org.springframework.web.servlet.DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse)mvc

上面代码中的标注 1,2,3:

  1. 根据handlerMapping获取执行链HandlerExecutionChain(不一样的请求映射关系是放在不懂的mapping中的,这里不一样的请求指的是不一样的controller或者是资源请求,这块是mvc的东西很少说了.),正常获取的mpping为requestMappingHandlerMapping
  2. 获取HandlerExecutionChain以后标注2的执行代码就是拦截器的执行

3. 标注3的执行代码正常的请求,此处不详解

2.拦截器从哪里来的

执行时期

  1. 获取全部的拦截器,发现拦截器是存放在 HandlerExecutionChain.interceptors中.
  2. HandlerExecutionChain 是在 org.springframework.web.servlet.DispatcherServlet.getHandler(HttpServletRequest)中返回的,说明HandlerExecutionChain.interceptors也是在这个时候别赋值的.
  3. DispatcherServlet.getHandler(HttpServletRequest)代码以下:

AbstractHandlerMapping.getHandlerExecutionChain(Object, HttpServletRequest)app

说明 HandlerExecutionChain interceptors 是 从 AbstractHandlerMapping.adaptedInterceptors中拿得值

spring启动时期

如今咱们知道了 执行的拦截器是从 AbstractHandlerMapping.adaptedInterceptors中拿到的

先看下AbstractHandlerMapping的结构,发现咱们上面说到的requestMappinghandlerMapping是它的子类,这个也就是咱们要讲的重点(requestMappinghandlerMapping的实例化过程)学习

这个地方先说下我看这段源码的思路

  1. 咱们须要探究的是AbstractHandlerMapping.interceptors.由于咱们getHandler中使用的是requestMappinghandlerMapping的实例.他们又是父子关系.因此interceptors是在requestMappingHandlerMapping实例化过程当中被添加进去的.
  2. 思路到了这个地方,要知道,一个实例spring建立的过程: 放入BeanDefinitionMap -> getBean()(这里springIoc的源码不说了,之后有时间在写).
  3. 在getBean的执行地方debug 条件为BeanName.equals("requestMappingHandlerMapping"),发现不是经过构造器建立的,是根据@bean建立的.

发现是在WebMvcConfigurationSupport.requestMappingHandlerMapping()

AbstractHandlerMapping.setInterceptors(Object...)

WebMvcConfigurationSupport.getInterceptors() spa

看了上面的代码你会发现addInterceptors是被咱们重写的

咱们把本身的拦截器传给了这个方法.

总结:

拦截器是在springmvc处理请求的时候执行debug

是在执行链中存放的.3d

执行链中的 interceptors 是从AbstractHandlerMapping中拿到的.代理

AbstractHandlerMapping 中的 拦截器 是在 requestMappingHandlerMapping 初始化的过程存放的.

requestMappingHandlerMapping 初始化的时候 会调用 WebMvcConfigurationSupport 中的 addInterceptors()方法

这个方法被咱们重写了,就是在使用 拦截器 的两个步骤中的 第二步 ,咱们把本身写的拦截器传了进去

相关文章
相关标签/搜索