找回密码
 立即注册
首页 业界区 业界 SpringBoot中的拦截器江湖

SpringBoot中的拦截器江湖

寇秀娟 2025-6-2 23:15:28
前言

很多小伙伴在工作中遇到拦截需求就无脑写HandlerInterceptor,结果被复杂场景搞得鼻青脸肿。
作为一名有多年开发经验的程序员,今天领大家到SpringBoot的山头认认6把交椅:
1.webp

这篇文章以梁山为背景的介绍SpringBoot中的拦截器,可能更通俗易懂。
希望对你会有所帮助,记得点赞和收藏。
第一把交椅:Filter

Filter是梁山中的总寨主。
典型战斗场面:全局鉴权/接口耗时统计
  1. @WebFilter("/*")
  2. public class CostFilter implements Filter {
  3.     @Override
  4.     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
  5.         long start = System.currentTimeMillis();
  6.         chain.doFilter(req, res); // 放行江湖令箭
  7.         System.out.println("接口耗时:"+(System.currentTimeMillis()-start)+"ms");
  8.     }
  9. }
复制代码
起义缘由:必须是最高寨主,因为他在Servlet容器滚刀肉层面出手。想当年有个兄弟在Filter里调用Spring Bean,结果NPE错杀千人(要用WebApplicationContextUtils拿Bean才是正解)
第二把交椅:HandlerInterceptor

HandlerInterceptor是梁山中的二当家。
必杀场景:接口权限验证/请求参数自动装填
  1. public class AuthInterceptor implements HandlerInterceptor {
  2.     @Override
  3.     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
  4.         String token = request.getHeader("X-Token");
  5.         if(!"vip666".equals(token)){
  6.             response.setStatus(403);
  7.             return false; // 关门放狗
  8.         }
  9.         return true;
  10.     }
  11. }
  12. // 衙门张贴告示
  13. @Configuration
  14. public class WebMvcConfig implements WebMvcConfigurer {
  15.     @Override
  16.     public void addInterceptors(InterceptorRegistry registry) {
  17.         registry.addInterceptor(new AuthInterceptor())
  18.                 .addPathPatterns("/api/**")
  19.                 .excludePathPatterns("/api/login");
  20.     }
  21. }
复制代码
二当家的雷区

  • postHandle里修改了Response但内容已提交(注意response.isCommitted()判断)
  • 拦截资源请求要配置静态路径排出(例如/exclude/**)
  • 多拦截器顺序要调准确(Order值越小越早执行)
第三把交椅:AOP拦截器

AOP是梁山中的军师智多星。
运筹帷幄场景:服务层方法缓存/事务管理
  1. @Aspect
  2. @Component
  3. public class CacheAspect {
  4.     @Around("@annotation(com.example.anno.Cacheable)")
  5.     public Object aroundCache(ProceedingJoinPoint jp) {
  6.         String cacheKey = buildKey(jp);
  7.         Object cacheVal = redisTemplate.opsForValue().get(cacheKey);
  8.         if(cacheVal != null) return cacheVal;
  9.         
  10.         Object result = jp.proceed();
  11.         redisTemplate.opsForValue().set(cacheKey, result, 5, TimeUnit.MINUTES);
  12.         return result;
  13.     }
  14. }
复制代码
军师锦囊

  • 只可拦截Spring管理的Bean(new的对象拦截不了)
  • 与Transactional注解的顺序要注意(建议AOP切面Order大于事务切面)
  • 自定义注解要写在接口方法上才生效(要是实现类方法需要用@within)
第四把交椅:RestTemplate拦截器

RestTemplate是梁山中的水军头领。
远程战事:统一添加请求头/加密请求参数
  1. public class TraceInterceptor implements ClientHttpRequestInterceptor {
  2.     @Override
  3.     public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) {
  4.         request.getHeaders().add("X-TraceId", UUID.randomUUID().toString());
  5.         return execution.execute(request, body);
  6.     }
  7. }
  8. // 注册水军
  9. @Bean
  10. public RestTemplate restTemplate() {
  11.     RestTemplate rt = new RestTemplate();
  12.     rt.getInterceptors().add(new TraceInterceptor());
  13.     return rt;
  14. }
复制代码
总督黑历史

  • 编码问题:body若是字符串需要自行转字节数组(避免乱码)
  • 多次拦截:拦截器按添加顺序执行(第一个最后执行)
  • 访问HTTPS需要额外配置SSL(记得补上SSLContext)
第五把交椅:Feign拦截器

Feign拦截器是梁山中的外交使节。
出使外国:统一签名计算/Header透传
  1. public class FeignAuthInterceptor implements RequestInterceptor {
  2.     @Override
  3.     public void apply(RequestTemplate template) {
  4.         template.header("Authorization", "Bearer " + SecurityContext.getToken());
  5.     }
  6. }
  7. // 缔结合约
  8. @Configuration
  9. public class FeignConfig {
  10.     @Bean
  11.     public FeignAuthInterceptor feignAuthInterceptor() {
  12.         return new FeignAuthInterceptor();
  13.     }
  14. }
复制代码
使节烫手山芋

  • GET请求Body丢失问题(要自己特殊处理)
  • Form表单参数要手动编码(使用feign-form扩展)
  • Path参数需要Expression表达式解析(动态值要用@Param注明)
第六把交椅:WebFilter

WebFilter是梁山中的特种兵。
闪电战场景:响应式编程统一编码/跨域处理
  1. @Component
  2. public class CorsWebFilter implements WebFilter {
  3.     @Override
  4.     public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
  5.         ServerHttpResponse response = exchange.getResponse();
  6.         response.getHeaders().add("Access-Control-Allow-Origin", "*");
  7.         return chain.filter(exchange);
  8.     }
  9. }
复制代码
作战条件

  • 必须在WebFlux环境下(传统MVC无效)
  • 响应式编程模式(函数式声明)
  • 非阻塞管道(异步要配合Mono/Flux)
各派武功排行榜

门派攻击范围招式复杂度内力消耗首选战场Filter全局最外层★★☆☆☆低安全校验/日志记录HandlerMVC控制器层★★★☆☆中权限控制AOP业务方法级★★★★☆高缓存/事务RestTemplateHTTP客户端★★★☆☆中服务间调用Feign声明式客户端★★★★☆高微服务通信WebFilter响应式全链路★★★★★极高WebFlux应用武林秘笈

1. 顺序就是力量

Filter -> Interceptor -> AOP ,越早拦截越省力(但别在Filter里做业务)
2. 量力而行选兵器


  • 简单鉴权用HandlerInterceptor
  • 方法级管控上AOP
  • 微服务用FeignInterceptor
3. 性能损耗要监控

用Arthas监控拦截链路耗时,避免拦截器连环夺命call
  1. # 查看HandlerInterceptor耗时
  2. trace *.preHandle '#cost>10'
  3. # 诊断AOP切面
  4. watch com.example.aop.*Aspect * '{params,returnObj}' -x 3
复制代码
最后送给各位江湖儿女一句话:拦截是门艺术,别让好刀砍了自己人!
最后说一句(求关注,别白嫖我)

如果这篇文章对您有所帮助,或者有所启发的话,帮忙关注一下我的同名公众号:苏三说技术,您的支持是我坚持写作最大的动力。
求一键三连:点赞、转发、在看。
关注公众号:【苏三说技术】,在公众号中回复:进大厂,可以免费获取我最近整理的50万字的面试宝典,好多小伙伴靠这个宝典拿到了多家大厂的offer。
本文收录于我的技术网站:http://www.susan.net.cn

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册