目录
内容
通过debug看请求处理过程,从归属、位置、执行时机、接口定义、使用场景等多维度对比Filter和Interceptor,同时也列举了两者的相同点。
一张图看差异
请求处理流程
流程涉及的主要类
- 找到URI对应的servlet
org.apache.catalina.connector.CoyoteAdapter#service
org.apache.catalina.connector.CoyoteAdapter#postParseRequest
org.apache.catalina.mapper.Mapper#map(org.apache.tomcat.util.buf.MessageBytes, org.apache.tomcat.util.buf.MessageBytes, java.lang.String, org.apache.catalina.mapper.MappingData)
org.apache.catalina.mapper.Mapper#internalMap
org.apache.catalina.mapper.Mapper#internalMapWrapper
- 获取servlet实例,filterChain实例
org.apache.catalina.core.StandardWrapperValve#invoke
- 调用filterChain中的下一个filter,若已无filter,则调用servlet。
org.apache.catalina.core.ApplicationFilterChain#doFilter
org.springframework.web.servlet.DispatcherServlet#doDispatch
- 调用拦截器的preHandle
org.springframework.web.servlet.HandlerExecutionChain#applyPreHandle
- 找到controller的method并执行
org.springframework.web.servlet.HandlerAdapter#handle
- 调用拦截器postHandle
org.springframework.web.servlet.HandlerExecutionChain#applyPostHandle
- 渲染view,调用拦截器afterCompletion
org.springframework.web.servlet.DispatcherServlet#processDispatchResult
org.springframework.web.servlet.DispatcherServlet#render
org.springframework.web.servlet.HandlerExecutionChain#triggerAfterCompletion
归属差异
- Filter归属javax.servlet
- Interceptor归属SpringMVC
位置差异
- Filter在Application/Container范围
- Interceptor在MVC框架范围
执行时机差异
- container处理请求,先调用filter,然后调用servlet
- mvc dispatcherServlet处理请求,在controller、view的前后调用interceptor
接口定义差异
Filter接口
- javax.servlet.Filter#init Container调用,Filter实例化后的初始化行为
- javax.servlet.Filter#doFilter 过滤请求
- javax.servlet.Filter#destroy Container调用,销毁Filter时调用,如释放资源。
Interceptor接口
- org.springframework.web.servlet.HandlerInterceptor#preHandle 获取合适的handler之后,adapter调用handler之前。
- org.springframework.web.servlet.HandlerInterceptor#postHandle adapter调用handler之后,渲染view之前,可以向ModelAndView额外暴露数据
- org.springframework.web.servlet.HandlerInterceptor#afterCompletion 请求处理流程结束之后,即view渲染之后,可以用于资源清理。
使用场景差异
Filter侧重应用级别的行为
- 验证登录
- request或response转化
- 处理单点登录SSO(SingleSignOn)
Interceptor侧重功能级别的行为
- 事前验证 授权检查、form表单token验证
- 事前事后联合使用 事前准备/事后清除ThreadLocal数据,如session数据
- 修改view的theme主题
相同点
- 都是接口
- 都可以控制请求处理流程
- Filter可决定是否调用filterChain.doFilter
- Interceptor preHandle可决定返回true\false
- 责任链设计模式
- org.apache.catalina.core.ApplicationFilterChain#filters
- org.springframework.web.servlet.HandlerExecutionChain#interceptors