详细讲一下过滤器和拦截器(持续更新)

168 阅读2分钟

过滤器和拦截器

二者区别

过滤器(filter)
拦截器(intercepter)
过滤器是在servlet学的,拦截器是在springmvc学的

实现逻辑

过滤器:实现Filter接口,重写init()、doFilter()、destroy()三个方法
拦截器:实现HandlerInterceptor接口,重写preHandle()、postHandle()、afterCompletion()三个方法。

相比过滤器,拦截器的实现方法更不好理解
拦截器是链式调用,一个应用可以存在多个拦截器,一个请求可以触发多个拦截器,每个拦截器的调用根据声明顺序依次执行。

  • preHandle():在请求处理前调用,如果返回false,请求直接结束,拦截器失效。
  • postHandle():拦截器的处理逻辑。在多个拦截器同时作用时,postHandle()的调用顺序和preHandle()相反(先进的后出)
  • afterCompletion():在整个请求结束后执行的逻辑。

过滤器和拦截器都体现了AOP的编程思想。

过滤器和拦截器底层实现逻辑不同

过滤器基于函数回调
拦截器基于反射(动态代理)实现(下面的方法参数省略)

我们自定义的过滤器,实现了doFilter()方法,实际上我们处理逻辑是filterChain.doFilter(),ApplicationFilterChain是这个filterChain参数的实现类,这个类里有一个doFilter(),这就是回调方法。

每个xxxFilter执行doFliter()过滤逻辑后,执行filterChain.doFilter(),实现函数回调。

过滤器和拦截器使用范围不同

过滤器实现的javax.servlet.Filter接口,是在servlet规范中定义的,也就是说过滤器依赖Tomcat等容器,所以只能在web程序中使用。

拦截器是一个spring组件,由spring容器管理,可以单独使用,不必依赖web服务器。

过滤器和拦截器触发时机不同

执行逻辑.png 过滤器几乎可以对所有进入容器中的请求起作用,而拦截器只会对controller中请求或者静态资源的访问起作用

拦截器加载的时间点在spring将对象注入容器之前,所以在拦截器类中使用@Autowired注册会失效

生命周期

一个过滤器实例只能在容器初始化时调用一次
拦截器充分体现了AOP思想,例如在调用某方法前实现逻辑,在调用后实现逻辑等。
一个拦截器实例在一个controller生命周期内可以多次调用。