过滤器和拦截器
二者区别
过滤器(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服务器。
过滤器和拦截器触发时机不同
过滤器几乎可以对所有进入容器中的请求起作用,而拦截器只会对controller中请求或者静态资源的访问起作用
拦截器加载的时间点在spring将对象注入容器之前,所以在拦截器类中使用@Autowired注册会失效
生命周期
一个过滤器实例只能在容器初始化时调用一次
拦截器充分体现了AOP思想,例如在调用某方法前实现逻辑,在调用后实现逻辑等。
一个拦截器实例在一个controller生命周期内可以多次调用。