过滤器和拦截器的区别之处

过滤器

  • filter接口中定义了三个方法
  1. init():Filter的整个生命周期被调用一次
  2. destroy():Filter的整个生命周期被调用一次
  3. dofilter():容器的每一次请求都调用该方法,FilterChain用来调用下一个过滤器Filter

拦截器

  • 拦截器是链式调用,一个应用中可以同时存在多个拦截器Interceptor, 一个请求也可以触发多个拦截器 ,而每个拦截器的调用会依据它的声明顺序依次执行。
  • 拦截器也定义了三个方法:
  1. preHandle:这个方法在请求处理前调用
  2. postHandle:在preHandle返回值为true时才执行
  3. afterCompletion:只有在 preHandle() 方法返回值为true 时才会执行。在整个请求结束之后, DispatcherServlet 渲染了对应的视图之后执行.

不同之处

实现原理不同

过滤器 是基于函数回调的,拦截器 则是基于Java的反射机制(动态代理)实现的。

使用范围不同

  • 我们看到过滤器 实现的是 javax.servlet.Filter 接口,而这个接口是在Servlet规范中定义的,也就是说过滤器Filter 的使用要依赖于Tomcat等容器,导致它只能在web程序中使用。
  • 而拦截器(Interceptor) 它是一个Spring组件,并由Spring容器管理,并不依赖Tomcat等容器,是可以单独使用的。不仅能应用在web程序中,也可以用于Application、Swing等程序中。

触发时机不同

过滤器和拦截器的区别之处

  • 过滤器Filter是在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后。
  • 拦截器 Interceptor 是在请求进入servlet后,在进入Controller之前进行预处理的,Controller 中渲染了对应的视图之后请求结束。

拦截的请求范围不同

过滤器几乎可以对所有进入容器的请求起作用,而拦截器只会对Controller中请求或访问static目录下的资源请求起作用。

注入bean情况不同

  • 过滤器正常注入
  • 但是拦截器报异常,注入的是null,这是因为拦截器加载的时间点在springcontext之前,而Bean又是由spring进行管理。
    ------ 解决方案也很简单,我们在注册拦截器之前,先将Interceptor 手动进行注入。「注意」:在registry.addInterceptor()注册的是getMyInterceptor() 实例。

控制执行顺序不同

  • 过滤器用@Order注解控制执行顺序,通过@Order控制过滤器的级别,值越小级别越高越先执行。
  • 拦截器默认的执行顺序,就是它的注册顺序,也可以通过Order手动设置控制,值越小越先执行。
  • 要知道controller 中所有的请求都要经过核心组件DispatcherServlet路由,都会执行它的 doDispatch() 方法,而拦截器postHandle()、preHandle()方法便是在其中调用的。