一,过滤器:
使用过滤器直接继承Filter接口即可,也可以通过@WebFilter注解对特定的URL拦截。拦截器三个主要的方法,init()初始化方法,doFilter()容器中的每一次请求都会调用此方法,destory()容器销毁时调用,一般用于销毁或关闭资源,真整个生命周期只会调用一次。
二,拦截器
拦截器是链式调用,一个应用中可以同时存在多个拦截器,一个请求可以触发多个拦截器,先声明先调用(可以指定优先级通过@Order注解),拦截器中的三个方法,preHandle()请求之前调用,返回true才会放行进入控制器,postHandle()控制器执行之后和DispatcherServelet返回渲染视图之前调用,这里注意,先声明的后调用(主要是spring的内部执行有关),afterComplation()在DispatcherDServlet 渲染视图之后执行。
过滤器和拦截器的不之处:
1,过滤器和拦截器都体现了AOP思想,但底层实现大不相同,顾虑器是基于函数回调实现的,而拦截器是基于java的反射机制,也就是动态代理实现的。
这里重点说下过滤器,顾虑器有个参数是FilterChain,实际上他是一个回调接口,ApplicationFilterChain是他的是实现类,这个类内部也有的一个doFilter()方法,就是毁掉方法。AplicationFilterChain内部会拿到所有的自定义xxxFilter类,然后依次调用每个xxxFilter的doFilter方法。而每个xxxFilter 会先执行自身的 doFilter() 过滤逻辑,最后在执行结束前会执行filterChain.doFilter(servletRequest, servletResponse),也就是回调ApplicationFilterChain的doFilter() 方法,以此 循环执行实现函数回调。
,2,适用范围的不同
过滤器是servlet规范中定义的,依赖于tomcat容器,只能在web应用中使用,e而拦截器是spring的组件,由spring管理,不依赖于tomcat,可以单独使用,也可以在Apilcation,swing等程序中使用。
3,触发时机不同
可以看下下面这张图;
过滤器是请求进入tomcat容器后,在进入servlet之前进行预处理,结束于servlet处理完之后;而拦截器是进入servlet之后,在进入控制器之前进行预处理,结束于页面渲染完成之后。
4,拦截的请求范围不同
过滤器几乎对所有进入容器的请求和访问静态资源的请求都会起作用,而拦截器只会对进去控制器的请求起作用。
5,注入Bean的情况不同
过滤器中可以直接注入Bean对象,而拦截器中是无法直接注入Bean对象的,因为拦截器加载的时间点是在SpringContext之前,而Bean又是由spring管理得,所以无法注入Bean对象,如果想要在拦截器中注入Bean对象,则需要在注册拦截器之前手动注入。
6,执行顺序不同
过滤器可以使用@Order注解控制执行顺序,值越小,优先级越高
拦截器默认按照注册顺序执行,也可以使用@Order注解控制执行顺序,但拦截器的后置处理方法则是按照栈规则执行,也就是先注册的拦截器,它的后置处理方法会延后执行,这个是根据spring的过滤器数组的applyPostHandle方法的逆序执行有关。