SpringMVC___拦截器与过滤器进行比较分析,流程以及DispatcherServlet中央控制器与Servlet的关系

SpringMVC中的拦截器对应了Web基础中的过滤器。
关于过滤器可以看我写的博客:https://www.cnblogs.com/zhangsonglin/p/10774409.html
对比拦截器和过滤器来理解拦截器

一、拦截器与过滤器的区别:

1、拦截器不依赖与servlet容器是SpringMVC自带的,过滤器依赖于Servlet容器。
2、拦截器是基于java的反射机制的,而过滤器是基于函数回调。
3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
4、拦截器可以访问controller上下文、值栈里的对象,而过滤器不能访问。
(拦截器的preHandle方法在进入controller执行,而拦截器的postHandle方法在执行完controller业务流程后,在视图解析器解析ModelAndView之前执行,可以操控Controller的ModelAndView内容。,而afterCompletion是在视图解析器解析渲染ModelAndView完成之后执行的)( 过滤器是在服务器启动时就会创建的,只会创建一个实例,常驻内存,也就是说服务器一启动就会执行Filter的init(FilterConfig config)方法.当Filter被移除或服务器正常关闭时,会执行destroy方法)

5、拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
(关于这句话的解读是:我们知道拦截器是SprinMVC自带的,而SpringMVC存在Controller层的,而controller层可以访问到service层,service层是不能访问service层的,而过滤器是客户端和服务端之间请求与响应的过滤)

6、过滤器和拦截器触发时机、时间、地方不一样
(过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前,如果看不懂可以看7完后再来理解)

7、过滤器包裹住servlet,servlet包裹住拦截器。

我们知道在一般javaweb中Servlet的doService()方法是类似调度的功能,调用doGet、doPost等钩子函数。


而我们知道过滤器中的doFilter方法中chain.doFilter(request, response)就会对请求放行,chain.doFilter(request, response)之前的都是还没有进入Servlet容器的,而chain.doFilter(request, response)之后的就放行了,进入了Servlet容器,这个hain.doFilter(request, response)就像个门,门内门外。
   
   事实上调用Servlet的doService()方法是在chain.doFilter(request, response);这个方法中进行的

拦截器是被包裹在过滤器中的,为什么了?
因为:
  a.preHandle()这个方法是在过滤器的chain.doFilter(request, response)方法的前一步执行,也就是在chain.doFilter(request, response)]之间执行。
 
  b.preHandle()方法之后,在return ModelAndView之前进行,可以操控Controller的ModelAndView内容。
 
  c.afterCompletion()方法是在过滤器返回给前端前一步执行,也就是在chain.doFilter(request, response)之间执行。

在结合SpringMVC流程来理解拦截器前先说明一下,为什么SpringMVC可以使用Servle以及HttpServlet等。

我们知道url请求要找到对应Handle以及返回相关对象等调度问题都是由前端控制器也叫中央控制器DispatcherServlet来操作的,而我们查看一波DispatcherServlet源码,可以发现,中央控制器也是HttpServlet的子类,那么真相就大白了。

图为SpringMVC流程图,那么拦截器发生的过程是在哪了?

结合两图来看:

用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获;
DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI),然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器对象)最后以HandlerExecutionChain对象的形式返回;
3.DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(…)方法)

借鉴于大佬,加上了许多自己的理解:
https://www.cnblogs.com/panxuejun/p/7715917.html
https://dpb-bobokaoya-sm.blog.csdn.net/article/details/87970484

猜你喜欢

转载自www.cnblogs.com/zhangsonglin/p/10961030.html