全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-18 6 分钟 ✍️ juanwangdev

Spring MVC 多个拦截器的执行顺序

Spring MVC支持配置多个拦截器,它们的执行顺序遵循特定规则,理解这些规则对正确设计拦截链至关重要。

注册顺序决定执行顺序

Java
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 按注册顺序配置拦截器
        registry.addInterceptor(interceptorA)
            .addPathPatterns("/**");

        registry.addInterceptor(interceptorB)
            .addPathPatterns("/**");

        registry.addInterceptor(interceptorC)
            .addPathPatterns("/**");
    }
}

执行顺序规则

Java
请求进入
    ↓
preHandle(A) → preHandle(B) → preHandle(C)   【顺序执行】
    ↓
Controller处理
    ↓
postHandle(C) → postHandle(B) → postHandle(A) 【逆序执行】
    ↓
视图渲染
    ↓
afterCompletion(C) → afterCompletion(B) → afterCompletion(A) 【逆序执行】
方法执行顺序说明
preHandle顺序执行先注册先执行
postHandle逆序执行后注册先执行
afterCompletion逆序执行后注册先执行

执行流程图解

Java
Interceptor A   Interceptor B   Interceptor C
    ↓               ↓               ↓
preHandle(A) ─→ preHandle(B) ─→ preHandle(C)
                                    ↓
                                Controller
                                    ↓
postHandle(C) ←─ postHandle(B) ←─ postHandle(A)
                                    ↓
                                View渲染
                                    ↓
afterCompletion(C)←─ afterCompletion(B)←─ afterCompletion(A)
                                    ↓
                                响应完成

代码验证示例

Java
@Component
public class InterceptorA implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request,
                            HttpServletResponse response,
                            Object handler) {
        log.info("InterceptorA - preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response,
                           Object handler,
                           ModelAndView modelAndView) {
        log.info("InterceptorA - postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response,
                                Object handler,
                                Exception ex) {
        log.info("InterceptorA - afterCompletion");
    }
}

@Component
public class InterceptorB implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request,
                            HttpServletResponse response,
                            Object handler) {
        log.info("InterceptorB - preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response,
                           Object handler,
                           ModelAndView modelAndView) {
        log.info("InterceptorB - postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response,
                                Object handler,
                                Exception ex) {
        log.info("InterceptorB - afterCompletion");
    }
}

执行日志输出:

Java
InterceptorA - preHandle
InterceptorB - preHandle
InterceptorC - preHandle
Controller处理...
InterceptorC - postHandle
InterceptorB - postHandle
InterceptorA - postHandle
InterceptorC - afterCompletion
InterceptorB - afterCompletion
InterceptorA - afterCompletion

preHandle返回false的影响

当某个拦截器的preHandle返回false时,后续拦截器不再执行:

text
@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(interceptorA)
        .addPathPatterns("/**");

    registry.addInterceptor(interceptorB)
        .addPathPatterns("/**");
}

如果InterceptorA的preHandle返回false:

text
preHandle(A) → 返回false,请求被拦截
    ↓
后续拦截器B的preHandle不执行
    ↓
Controller不执行
    ↓
所有postHandle不执行
    ↓
afterCompletion(A)执行(已执行preHandle的拦截器)
    ↓
InterceptorB的afterCompletion不执行

order()方法控制顺序

text
@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(interceptorA)
        .addPathPatterns("/**")
        .order(3);    // order值越大,优先级越低

    registry.addInterceptor(interceptorB)
        .addPathPatterns("/**")
        .order(1);    // order值越小,优先级越高

    registry.addInterceptor(interceptorC)
        .addPathPatterns("/**")
        .order(2);
}

使用order后的执行顺序:

text
preHandle: B(order=1) → C(order=2) → A(order=3)
postHandle: A(order=3) → C(order=2) → B(order=1)
afterCompletion: A(order=3) → C(order=2) → B(order=1)

order值越小的拦截器,preHandle越先执行,postHandle和afterCompletion越后执行。

实际应用场景

text
@Override
public void addInterceptors(InterceptorRegistry registry) {
    // 1. 性能监控拦截器 - 最先执行(order最小)
    registry.addInterceptor(performanceInterceptor())
        .addPathPatterns("/**")
        .order(1);

    // 2. 日志记录拦截器
    registry.addInterceptor(logInterceptor())
        .addPathPatterns("/**")
        .order(2);

    // 3. 认证拦截器
    registry.addInterceptor(authInterceptor())
        .addPathPatterns("/api/**")
        .order(3);

    // 4. 权限拦截器 - 在认证之后执行
    registry.addInterceptor(permissionInterceptor())
        .addPathPatterns("/api/**")
        .order(4);
}

异常情况下的执行顺序

当Controller抛出异常时:

text
preHandle(A) → preHandle(B) → preHandle(C)  正常执行
    ↓
Controller抛出异常
    ↓
postHandle均不执行
    ↓
afterCompletion(C) → afterCompletion(B) → afterCompletion(A)  正常执行(逆序)

Controller异常时postHandle不执行,但afterCompletion仍会正常执行(逆序)。

要点总结

  • preHandle按注册顺序执行(先注册先执行)
  • postHandle和afterCompletion逆序执行(后注册先执行)
  • preHandle返回false会中断后续拦截器执行
  • order()方法可显式控制执行顺序,值越小优先级越高
  • Controller异常时postHandle不执行,afterCompletion仍执行

📝 发现内容有误?点击此处直接编辑

← 上一篇 Spring MVC preHandle方法详解
下一篇 → Spring MVC 实现HandlerInterceptor接口
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库