过滤器和拦截器的区别之处
过滤器
- filter接口中定义了三个方法
- init():Filter的整个生命周期被调用一次
- destroy():Filter的整个生命周期被调用一次
- dofilter():容器的每一次请求都调用该方法,FilterChain用来调用下一个过滤器Filter
拦截器
- 拦截器是链式调用,一个应用中可以同时存在多个拦截器Interceptor, 一个请求也可以触发多个拦截器 ,而每个拦截器的调用会依据它的声明顺序依次执行。
- 拦截器也定义了三个方法:
- preHandle:这个方法在请求处理前调用
- postHandle:在preHandle返回值为true时才执行
- 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()方法便是在其中调用的。