本文主要记录本身学习过程,若有错误请指出
一.用法
1.常引用拦截器 : HandlerInterceptor
代码以下:web
上图代码中 myMyHandlerInterceptor 注意:
- 实现HandlerInterceptor接口
- @Component 注解
如今spring-ioc 容器中已经存在我本身建立的拦截器,可是还要把它WebMvcConfigurationSupport(后面会讲为啥要交给它管理)spring
代码以下:spring-mvc
要完成对拦截器的使用,上图代码中注意两点:
- 重写 addInterceptors 方法
- @Configuration
上述作法以后可使用 拦截器了
二.源码
看源码 逆向思惟 -> 拦截器在哪里执行的 -> 拦截器是哪里来的
1.拦截在哪里执行的
- 我看到网上有不少说拦截器的实现原理是动态代理,其实并非, aop的实现原理是动态代理
- 拦截器的实现原理是执行链 HandlerExecutionChain
- 这个过程是HandlerExecutionChain是spring-mvc(由于这个文章记录的是拦截器,不会多说springmvc的东西) 中产生的.
执行代码以下: org.springframework.web.servlet.DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse)mvc
上面代码中的标注
1,2,3:
- 根据handlerMapping获取执行链HandlerExecutionChain(不一样的请求映射关系是放在不懂的mapping中的,这里不一样的请求指的是不一样的controller或者是资源请求,这块是mvc的东西很少说了.),正常获取的mpping为requestMappingHandlerMapping
- 获取HandlerExecutionChain以后标注2的执行代码就是拦截器的执行
3.
标注3的执行代码正常的请求,此处不详解
2.拦截器从哪里来的
执行时期
- 获取全部的拦截器,发现拦截器是存放在 HandlerExecutionChain.interceptors中.
- HandlerExecutionChain 是在 org.springframework.web.servlet.DispatcherServlet.getHandler(HttpServletRequest)中返回的,说明HandlerExecutionChain.interceptors也是在这个时候别赋值的.
- DispatcherServlet.getHandler(HttpServletRequest)代码以下:
AbstractHandlerMapping.getHandlerExecutionChain(Object, HttpServletRequest)app
说明
HandlerExecutionChain interceptors 是 从
AbstractHandlerMapping.adaptedInterceptors中拿得值
spring启动时期
如今咱们知道了 执行的拦截器是从 AbstractHandlerMapping.adaptedInterceptors中拿到的
先看下AbstractHandlerMapping的结构,发现咱们上面说到的requestMappinghandlerMapping是它的子类,这个也就是咱们要讲的重点(requestMappinghandlerMapping的实例化过程)学习
这个地方先说下我看这段源码的思路
- 咱们须要探究的是AbstractHandlerMapping.interceptors.由于咱们getHandler中使用的是requestMappinghandlerMapping的实例.他们又是父子关系.因此interceptors是在requestMappingHandlerMapping实例化过程当中被添加进去的.
- 思路到了这个地方,要知道,一个实例spring建立的过程: 放入BeanDefinitionMap -> getBean()(这里springIoc的源码不说了,之后有时间在写).
- 在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()方法
这个方法被咱们重写了,就是在使用 拦截器 的两个步骤中的 第二步 ,咱们把本身写的拦截器传了进去