Spring Boot异常栈出现大量doFilterInternal是否正常?
问题分析与解答
异常栈出现大量doFilterInternal调用的原因
这种情况不正常,正常请求链路中doFilterInternal只会被调用一次(对应当前请求的Filter链执行),大量重复调用说明代码逻辑存在问题,核心原因集中在Filter注册、异常处理或切面逻辑的错误上。
可能的代码违规点排查
Filter重复注册
检查是否通过多种方式重复注册了同一个Token鉴权Filter:比如同时用@Bean和FilterRegistrationBean注册,或者在配置类中多次将该Filter添加到过滤链中。重复注册会导致每次请求都要经过多个相同的Filter实例,异常栈自然会出现大量doFilterInternal调用记录。Filter异常处理逻辑错误
查看doFilterInternal方法是否存在循环调用或异常重复抛出的逻辑,比如:
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { try { // Token鉴权逻辑 chain.doFilter(request, response); } catch (Exception e) { // 错误示例:再次调用chain.doFilter导致循环执行 chain.doFilter(request, response); } }
这种错误会让Filter被反复调用,直接导致异常栈中出现大量相同的方法记录。
- 单例Filter的线程安全问题
Filter默认是单例的,如果Filter中使用了非线程安全的成员变量(比如没有用ThreadLocal存储请求相关数据,而是直接用类成员变量),并发请求时会导致请求上下文混乱,间接引发异常的异常传递路径。比如:
// 错误示例:非线程安全的成员变量 private String currentToken; @Override protected void doFilterInternal(...) { currentToken = extractToken(request); // 并发场景下会被不同请求覆盖 // ... }
- 日志切面的异常处理错误
检查@Around切面的环绕逻辑,是否在Controller捕获异常后,又错误地重新抛出了该异常:
@Around("execution(* com.example.controller..*(..))") public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { try { Object result = joinPoint.proceed(); // 日志逻辑 return result; } catch (Exception e) { // 错误:重新抛出已被Controller捕获的异常,导致异常回传到Filter链 throw e; } }
这种情况下,Controller捕获了异常,但切面又将异常抛出,异常会进入Filter链,最终在异常栈中留下Filter的调用记录。
排查建议
- 先核对Filter的注册代码,确保只注册了一次Token鉴权Filter;
- 调试
doFilterInternal方法,确认是否被多次调用,且每次调用对应同一个请求; - 梳理Filter和切面的异常处理逻辑,排查是否存在重复抛出或循环调用的情况;
- 检查Filter中的成员变量,确保所有请求相关数据都是线程安全的。
内容的提问来源于stack exchange,提问作者Trịnh Quang Minh
相关产品推荐
相关产品推荐

