过滤器与拦截器
过滤器与拦截器
- Filter在 Servlet 规范中定义,依赖于Servlet容器,被Servlet容器(如Tomcat)调用;Interceptor不依赖于Servlet容器,是SpringMVC框架的一个组件,归Spring IoC容器管理调用。因此可以通过注入等方式来获取其他Bean的实例,使用更方便
- Filter是基于函数回调的,而Interceptor则是基于动态代理的
- Filter只能在请求的前后使用,而Interceptor可以详细到每个方法
- Filter对几乎所有的请求起作用,包括静态资源、程序中定义的Servlet等;而Interceptor只能对handler请求起作用
- Filter方法包括init、doFilter和destroy,Interceptor方法有preHandle、postHandle、
afterCompletionFilter不能访问handler上下文、值栈里的对象,而Interceptor可以,得益于IoC容器,虽然还没到达handler,但程序启动后就扫描好了handler
过滤器原理
Servlet容器维护过滤器链,依次将过滤器应用于request
- Servlet程序:用户编写的代码,定义了 接受的请求url、接受的请求方法、接收到请求时要执行的业务逻辑等内容。也可以是图片、index.html等文件
- Servlet容器:运行Servlet程序的容器,是Servlet标准的实现者,如Tomcat、Undertow等,是Web容器的一种。会接收外界的http request并转发给Servlet程序。
- Servlet容器:运行Servlet程序的容器,是Servlet标准的实现者,如Tomcat、Undertow等,是Web容器的一种。会接收外界的http request并转发给Servlet程序。
Filter中定义了对哪些request进行拦截以及拦截的逻辑,以进行决定是否继续将请求发往Servlet程序、修改request、修改response 等操作。
- 多对多关系:一个Filter可作用于多个Servlet程序、也可多个Filter作用于同一Servlet程序
- FilterChain:由Servlet容器维护的内容,作用于同一Servlet程序的多个Filter会在request到来时被Servlet容器组装成一个FilterChain。
调用逻辑:由Servlet容器将链中的首个Filter应用到该request,还会把FilterChain对象传给该Filter,之后由当前Filter通过FilterChain对象通知下一Filter处理处理该request,后续同理
拦截器的原理
Spring IoC容器维护handler的拦截器列表【执行队列】,依次将拦截器应用于handler
传统的Java Web应用中后端可以有很多个Servlet程序,每个Servlet程序中有若干个handler;而SpringMVC中只有一个DispatcherServlet,当然允许用户也可以自己添加Servlet程序,由它将所有的请求根据请求path转发到相应的handler,项目启动时IoC容器会扫描所有的handler及应用到该handler的interceptor,因此DispatcherServlet会在转发请求到handler的前后执行interceptor的preHandl、postHandle、afterCompletion方法
过滤器和拦截器对比
过滤器是Filter调用FilterChain,FilterChain调用下一Filter的执行模式,这本质上是函数回调,要命的是函数调用栈会越来越深
过滤器是Filter调用FilterChain,FilterChain调用下一Filter的执行模式,这本质上是函数回调,要命的是函数调用栈会越来越深
不过当一个handler上有多个拦截器时,多个拦截器的执行顺序与多个filter的类似,即 L1 -> L2 ->handler -> L2 -> L1