Spring spring

Spring中文网站 > Spring Boot > Spring Boot拦截器和过滤器区别 Spring Boot拦截器的处理逻辑
Spring Boot拦截器和过滤器区别 Spring Boot拦截器的处理逻辑
发布时间:2026/06/30 14:51:55

品牌型号:联想ThinkPad X1

系统:Windows10家庭版

软件版本:Spring 5.3.7

做Spring Boot项目时,很多人都踩过坑,明明加了拦截器,结果有些请求还是拦不住,在换过滤器时,又发现拿不到想要的上下文信息。拦截器和过滤器两个东西用途不一样,混用起来让人很头疼。今天就来聊聊“Spring Boot拦截器和过滤器区别,Spring Boot拦截器的处理逻辑”,搞清楚这些以后,我们再遇到权限校验、日志记录这类需求,选哪个、怎么写,心里就有数了。

一、Spring Boot拦截器和过滤器区别

先说一个很多人忽略的点,过滤器是Servlet规范里的东西,跟Spring其实没什么关系,Tomcat、Jetty这些容器就能驱动它跑起来,而拦截器是Spring MVC自己的机制,依赖Spring容器,脱离Spring就用不了。这个差异,就直接决定了它们能做的事情不一样。

原生Servlet
图1:原生Servlet

我们从请求处理的位置来看,过滤器执行节点更靠前,请求进入容器后,先经过过滤器链,再进入DispatcherServlet,最后才轮到拦截器,所以过滤器能处理的范围更广,静态资源、错误页、非Spring管理的请求它都能拦到。拦截器只能处理走DispatcherServlet的请求,像直接访问静态文件这种,拦截器是看不见的。

自定义拦截器
图2:自定义拦截器

它们能拿到的东西也不一样,过滤器里只有原始的HttpServletRequest和HttpServletResponse,Spring的那些Bean、HandlerMethod之类的上下文信息它拿不到,但是拦截器就不同了,因为本身跑在Spring容器里,可以直接注入Service、拿到当前执行的Controller方法信息,做权限校验的时候灵活很多,比如根据注解判断某个接口要不要登录,在拦截器里实现会很自然。

Filter中无法注入Bean
图3:Filter中无法注入Bean

实际项目里怎么选?如果是处理编码、跨域、请求日志这类跟业务无关的通用逻辑,用过滤器比较合适,因为它覆盖范围广、执行早,如果是登录校验、权限控制、操作审计这类需要结合业务上下文的逻辑,拦截器更顺手。

二、Spring Boot拦截器的处理逻辑

拦截器的核心接口是HandlerInterceptor,实现它需要重写preHandle、postHandle、afterCompletion三个方法,很多人刚接触的时候觉得三个方法记起来麻烦,但其实对应的时机很好理解,请求到Controller之前、Controller执行完之后、整个请求结束之后,按这个顺序走下来就清楚了。

重写方法
图4:重写方法

preHandle是用得很多的一个,它在请求进Controller之前触发,返回值是个boolean,返回true请求继续往下走,返回false请求直接中断,登录校验基本都写在这里,token不对或者没登录,直接返回false后手动写入Response,后面的逻辑就不会执行了。这里还能拿到HandlerMethod对象,通过它可以读到目标方法上的注解,做接口级别的权限控制很方便。

preHandle方法
图5:preHandle方法

postHandle在Controller执行完、视图渲染之前触发,可以拿到ModelAndView。不过现在大多数项目都是前后端分离,直接返回JSON,这个方法用到的场景反而不多。afterCompletion是整个请求走完之后才执行,不管中间有没有抛异常都会触发,比较适合做资源清理、记录请求耗时这类收尾的事情,有点类似try-finally里finally代码块。

afterCompletion方法的使用
图6:afterCompletion方法的使用

多个拦截器同时存在的时候,执行顺序和注册顺序有关,preHandle按注册顺序正向执行,afterCompletion反向执行,跟栈的进出逻辑一样。

以上就是Spring Boot拦截器和过滤器区别,Spring Boot拦截器的处理逻辑的全部内容了。拦截器与过滤器各司其职、执行节点不同,搞清楚它们的执行时机和能拿到的上下文,选起来就不会纠结了。拦截器三个方法的分工也不复杂,实际写下来会发现逻辑很清晰。理解原理之后,不管是做登录校验还是权限控制,落地都会顺很多。

180 1563 6924