首先了解什么是过滤器什么是拦截器
①过滤器(Filter)
过滤器通过直接实现Filter接口实现,也可以通过@WebFilter注解实现特定的URL拦截
在Filter接口中定义了三个方法:
- init():在容器初始化调动过滤器时使用,在Filter整个生命周期中只会被调用一次
- doFilter():容器每一次请求都会调用该方法,进行实际的业务处理
- destroy():容器销毁时调用该方法,也就是停止web工程的时候
②拦截器 (Interceptor)
拦截器是链式调用的,通过HandlerInterceptor接口来实现的,一个请求可以触发多个拦截器,其中也包含三个方法
- preHandle() :这个方法将在请求处理之前进行调用。注意:如果该方法的返回值为false ,将视为当前请求结束,不仅自身的拦截器会失效,还会导致其他的拦截器也不再执行。
- postHandle():只有在 preHandle() 方法返回值为true 时才会执行。会在Controller 中的方法调用之后,DispatcherServlet 返回渲染视图之前被调用。 有意思的是:postHandle() 方法被调用的顺序跟 preHandle() 是相反的,先声明的拦截器 preHandle() 方法先执行,而postHandle()方法反而会后执行。
- afterCompletion():只有在 preHandle() 方法返回值为true 时才会执行。在整个请求结束之后, DispatcherServlet 渲染了对应的视图之后执行。
拦截器和过滤器都体现了AOP编程的思想,但他们的区别如下:
①实现原理不同
过滤器 是基于函数回调的,拦截器 则是基于Java的反射机制(动态代理)实现的。
②使用范围不同
过滤器Filter 的使用要依赖于Tomcat等容器,导致它只能在web程序中使用。
而拦截器 它是一个Spring组件,并由Spring容器管理,并不依赖Tomcat等容器,是可以单独使用的。不仅能应用在web程序中,也可以用于Application、Swing等程序中。
③触发时机不同
过滤器Filter是在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后。拦截器 Interceptor 是在请求进入servlet后,在进入Controller之前进行预处理的,Controller 中渲染了对应的视图之后请求结束。
④拦截请求的范围不同
对同一个请求,过滤器执行了2次,而拦截器只执行一次。因为过滤器几乎可以对所有进入容器的请求起作用,而拦截器只会对Controller中请求或访问static目录下的资源请求起作用。
拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用
拦截器可以访问action上下文、值栈里的对象,而过滤器不能
⑤注入Bean情况不同
拦截器可以获取IOC容器中的各个bean,而过滤器就不行
在拦截器里注入一个service,可以调用业务逻辑。拦截器可以获取ioc中的service bean实现业务逻辑
⑥控制执行顺序不同
过滤器用@Order注解控制执行顺序,通过@Order控制过滤器的级别,值越小级别越高越先执行。拦截器默认的执行顺序,就是它的注册顺序,也可以通过Order手动设置控制,值越小越先执行