品牌型号:联想ThinkPad X1
系统:Windows10家庭版
软件版本:Spring 5.3.7
用Spring Boot做项目时,拦截器是我们绕不开的工具,尤其在做登录校验、权限控制、接口耗时统计等功能时,经常会用到它。但真正用起来,问题也跟着来了,拦截器到底该怎么发挥作用?配了多个拦截器,执行顺序又是怎么定的?顺序乱了会不会影响业务逻辑?今天给大家介绍一下Spring Boot拦截器有什么用,Spring Boot拦截器执行顺序的相关内容,将这块逻辑理清楚,后续不管项目里加多少个拦截器,心里都有底。
一、Spring Boot拦截器有什么用
拦截器常用来实现登录校验,每次请求进来,先在preHandle里检查请求头有没有带token,有的话验证一下有效性,没问题再放行,验证失败直接返回401,这样不用在每个Controller方法里重复写校验逻辑,统一在拦截器里处理就行。如果配合@LoginRequired这类自定义注解,还能做到接口级别的控制。

我们有时候在后台管理系统中做权限控制时也会用到拦截器,不同角色能访问的接口不一样,普通员工不能调用管理员才有权限的接口。可以在拦截器里拿到当前用户的角色信息,再对比目标接口要求的权限,不满足就拦截返回403。这个逻辑如果分散写在各个Controller里,后期改起来会非常痛苦,集中放在拦截器里管理清晰得多。

接口耗时统计和请求日志也很适合放在拦截器里做,在preHandle里记一个开始时间,存到当前线程的ThreadLocal里,等afterCompletion触发的时候取出来算差值,就能拿到这次请求的耗时。请求路径、接口耗时、返回状态统一打日志,排查线上慢接口的时候有据可查,比事后猜测要靠谱多了。

除了这些,还有一些不那么显眼但实际很有用的场景,比如接口限流、重复提交拦截、多租户数据隔离的上下文注入等等。
二、Spring Boot拦截器执行顺序
拦截器的执行顺序与注册顺序是直接挂钩的,在WebMvcConfigurer的addInterceptors方法里,先addInterceptor的先执行,后加的后执行。preHandle按照注册顺序从上到下跑,afterCompletion反过来,从最后一个注册的往前执行。

如果想更精确地控制顺序,可以让拦截器实现ed接口,或者直接用@注解,数字越小优先级越高,preHandle越早执行,这个在拦截器分散在不同配置类里的时候特别有用,不用把所有拦截器都堆在同一个地方注册,各自声明优先级,顺序照样可控。

容易被忽略的是如果拦截器A的preHandle返回了false,拦截器B的preHandle就不会执行了,请求直接中断,但A的afterCompletion还是会被调用,已经走过preHandle的拦截器都会触发afterCompletion,这个行为跟很多人的直觉不太一样,初次碰到容易产生困惑,所以在afterCompletion里做资源清理的时候,不能假设请求一定是完整走完的。
实际项目里,登录校验拦截器一般配置在最前面,因为连登录都没过就没必要往后走了,然后权限校验紧跟其后,日志和耗时统计的拦截器放最后注册。这样preHandle虽然晚执行,但afterCompletion反而会先触发,能把整个请求生命周期都覆盖到。

以上就是Spring Boot拦截器有什么用,Spring Boot拦截器执行顺序的全部内容了。拦截器能做的事情不少,像登录校验、权限控制、日志统计这些功能都可以用拦截器来做,后期维护起来省心很多。执行顺序这块记住一点就行,preHandle按注册顺序正向走,afterCompletion反向收尾,某个拦截器中断了请求不影响已执行拦截器的afterCompletion触发。