Spring Boot 请求处理链路:Filter → Interceptor → AOP → ExceptionHandler 执行顺序详解

摘要:本文深入分析 Spring Boot Web 项目中 Filter、Interceptor、ExceptionHandler 和 Controller AOP 四类组件的执行顺序,从源码层面揭示其背后的设计原理。

一、问题引入

当一个 HTTP 请求进入 Spring Boot 应用时,会经历如下一条处理链路:

请求 → Filter → Interceptor → AOP(Controller) → Controller → AOP(Controller)
                                                                 ↓
请求 ← Filter ← Interceptor ← AOP(Controller) ← ExceptionHandler ←

本文目标:明确这四类组件的先后顺序,并从 Spring MVC 架构和 Servlet 规范的角度解释其原理。


二、四类组件概述

2.1 Filter(过滤器)

Filter 是 Servlet 规范定义的组件,位于整个链路的最外层。

  • 职责:请求预处理、响应后处理、通用逻辑(如登录校验、日志记录、跨域处理)
  • 配置方式@WebFilter + @ServletComponentScanFilterRegistrationBean
  • 作用范围:覆盖所有请求,包括静态资源
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        System.out.println("Filter 执行(请求前)");
        chain.doFilter(request, response); // 放行,执行后续链路
        System.out.println("Filter 执行(响应后)");
    }
}

2.2 Interceptor(拦截器)

Interceptor 是 Spring MVC 提供的组件,在 DispatcherServlet 内部工作。

  • 职责:请求级拦截,适合做业务无关的通用处理(如登录验证、权限校验)
  • 配置方式 implements WebMvcConfigurer + addInterceptors
  • 作用范围:仅拦截进入 Controller 的请求
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request,
                              HttpServletResponse response, Object handler) {
        System.out.println("Interceptor preHandle 执行");
        return true; // false 时直接短路,不继续后续链路
    }

    @Override
    public void postHandle(HttpServletRequest request,
                            HttpServletResponse response, Object handler,
                            ModelAndView modelAndView) {
        System.out.println("Interceptor postHandle 执行");
    }

    @Override
    public void afterCompletion(HttpServletRequest request,
                                  HttpServletResponse response, Object handler,
                                  Exception ex) {
        System.out.println("Interceptor afterCompletion 执行");
    }
}

2.3 ExceptionHandler(异常处理器)

ExceptionHandler 是 Spring MVC 统一异常处理的核心组件。

  • 职责:捕获 Controller 抛出的异常,返回统一的错误响应
  • 配置方式@ControllerAdvice + @ExceptionHandler
  • 作用范围:仅处理 Controller 层抛出的异常
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception e) {
        System.out.println("ExceptionHandler 捕获异常:" + e.getMessage());
        return ResponseEntity.status(500).body("系统错误");
    }
}

2.4 AOP 切面(Controller 增强)

AOP(Aspect-Oriented Programming)是 Spring 提供的面向切面编程能力,可以对 Controller 方法进行增强。

  • 职责:方法级横切关注点(如日志、事务、性能监控)
  • 配置方式@Aspect + @Component + 切入点表达式
  • 作用范围:精确到方法级别
@Aspect
@Component
public class ControllerAop {

    @Around("execution(* com.example.controller.*.*(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("AOP Before 执行");
        Object result = joinPoint.proceed();
        System.out.println("AOP After 执行");
        return result;
    }
}

三、执行顺序图解

完整执行顺序如下:

                    ┌─────────────────────────────────────────────────┐
                    │                   Filter Chain                  │
                    │  ┌──────────────────────────────────────────┐  │
                    │  │             DispatcherServlet            │  │
                    │  │  ┌────────────────────────────────────┐  │  │
                    │  │  │         HandlerInterceptor          │  │  │
                    │  │  │  ┌──────────────────────────────┐  │  │  │
                    │  │  │  │         Controller AOP        │  │  │  │
                    │  │  │  │  ┌────────────────────────┐   │  │  │  │
                    │  │  │  │  │      Controller        │   │  │  │  │
                    │  │  │  │  └────────────────────────┘   │  │  │  │
                    │  │  │  └──────────────────────────────┘  │  │  │
                    │  │  └────────────────────────────────────┘  │  │
                    │  └──────────────────────────────────────────┘  │
                    └─────────────────────────────────────────────────┘

执行顺序(请求):  Filter → Interceptor preHandle → AOP @Before → Controller
执行顺序(响应):  Controller → AOP @After → Interceptor postHandle → Filter
异常处理顺序:      Controller 异常 → AOP @AfterThrowing → ExceptionHandler
最终清理:         Interceptor afterCompletion

四、源码层面的原理分析

4.1 Filter 最先执行 —— Servlet 规范决定

Filter 运行在 Servlet 容器层,独立于 Spring 容器之外。请求到达顺序:

Tomcat/Jetty (Servlet Container)
    ↓
Filter Chain(Filter 1 → Filter 2 → ... → Filter N)
    ↓
DispatcherServlet(Spring MVC 前端控制器)

原理:Servlet 规范要求所有请求必须经过 Filter 链,这发生在 Spring DispatcherServlet 之前。

4.2 Interceptor 在 DispatcherServlet 内部 —— Spring MVC 调度

DispatcherServlet 的核心方法 doDispatch() 源码简化如下:

// DispatcherServlet.doDispatch() 简化逻辑
protected void doDispatch(HttpServletRequest request,
                           HttpServletResponse response) {
    // 1. 找到匹配的 Handler
    HandlerExecutionChain handler = getHandler(request);
    
    // 2. 应用 Interceptor 的 preHandle
    if (!handler.applyPreHandle(request, response)) {
        return; // preHandle 返回 false,直接短路
    }
    
    // 3. 执行业务逻辑(Controller)
    HandlerAdapter adapter = getHandlerAdapter(handler.getHandler());
    adapter.handle(request, response);
    
    // 4. 应用 Interceptor 的 postHandle
    handler.applyPostHandle(request, response);
    
    // 5. 处理异常(包含在 doDispatch 中或由容器处理)
}

结论:Interceptor 是在 DispatcherServlet 调用 Controller 之前之后执行的,因此它在 Filter 之后、Controller 之前。

4.3 Controller AOP 在 Interceptor 之后 —— AOP 代理机制

Spring AOP 的代理机制决定了它作用于方法级别:

实际执行链路:
Interceptor.preHandle()
    ↓
AOP Proxy(Spring 创建的代理对象)
    ↓
@Before 通知
    ↓
Controller 实际方法
    ↓
@After 通知
    ↓
@AfterReturning / @AfterThrowing
    ↓
Interceptor.postHandle()

原理

  1. Spring AOP 基于代理模式:对 Controller 创建 JDK 动态代理或 CGLIB 代理
  2. 方法调用被代理对象拦截,执行切面逻辑后再调用真实目标方法
  3. Interceptor 拦截的是代理对象的调用,而非直接调用 Controller
  4. 因此 AOP 在 Interceptor 之后执行(进入时),但在 Interceptor 之前返回(返回链路相反)

4.4 ExceptionHandler 最后处理 —— 异常传播机制

异常抛出时的处理顺序:
Controller 抛出异常
    ↓
AOP @AfterThrowing(如果配置)
    ↓
DispatcherServlet 异常处理
    ↓
@ExceptionHandler 捕获
    ↓
Interceptors afterCompletion(始终执行)
    ↓
Filter(响应后处理)

关键点

  1. @ExceptionHandler 只处理 Controller 层异常
  2. Filter 和 Interceptor 的异常不会进入 ExceptionHandler
  3. afterCompletion 无论是否有异常都会执行(用于资源清理)

五、实测验证

创建以下测试代码验证顺序:

5.1 Filter

@Component
@Order(1)
public class TestFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                      HttpServletResponse response,
                                      FilterChain chain)
            throws ServletException, IOException {
        System.out.println("=== 1. Filter 执行 ===");
        chain.doFilter(request, response);
        System.out.println("=== 1. Filter 结束 ===");
    }
}

5.2 Interceptor

@Component
public class TestInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request,
                              HttpServletResponse response, Object handler) {
        System.out.println("=== 2. Interceptor preHandle ===");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request,
                            HttpServletResponse response, Object handler,
                            ModelAndView mav) {
        System.out.println("=== 4. Interceptor postHandle ===");
    }

    @Override
    public void afterCompletion(HttpServletRequest request,
                                  HttpServletResponse response,
                                  Object handler, Exception ex) {
        System.out.println("=== 6. Interceptor afterCompletion ===");
    }
}

5.3 AOP 切面

@Aspect
@Component
public class TestAspect {
    @Around("execution(* com.example.controller.*.*(..))")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("=== 3. AOP @Before ===");
        Object result = pjp.proceed();
        System.out.println("=== 5. AOP @After ===");
        return result;
    }
}

5.4 ExceptionHandler

@ControllerAdvice
public class TestExceptionHandler {
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handle(Exception e) {
        System.out.println("=== ExceptionHandler 捕获异常 ===");
        return ResponseEntity.status(500).body(e.getMessage());
    }
}

5.5 Controller

@RestController
public class TestController {
    @GetMapping("/test")
    public String test() {
        System.out.println("=== 3.5. Controller 执行 ===");
        return "OK";
    }
}

5.6 执行结果

=== 1. Filter 执行 ===
=== 2. Interceptor preHandle ===
=== 3. AOP @Before ===
=== 3.5. Controller 执行 ===
=== 5. AOP @After ===
=== 4. Interceptor postHandle ===
=== 6. Interceptor afterCompletion ===
=== 1. Filter 结束 ===

六、异常场景的执行顺序

6.1 Controller 抛出异常

=== 1. Filter 执行 ===
=== 2. Interceptor preHandle ===
=== 3. AOP @Before ===
=== 3.5. Controller 执行(抛出异常)===
=== ExceptionHandler 捕获异常 ===
=== 6. Interceptor afterCompletion ===
=== 1. Filter 结束 ===

注意postHandle 不会执行,因为异常在 postHandle 之前抛出。

6.2 Interceptor preHandle 返回 false

=== 1. Filter 执行 ===
=== 2. Interceptor preHandle 返回 false ===
=== 1. Filter 结束 ===

注意:后续所有组件都不执行。


七、各组件职责对比

组件位置职责场景异常处理范围
FilterServlet 容器层跨系统关注点(认证、日志、跨域)所有异常(需 try-catch)
InterceptorSpring MVC请求级拦截(权限、登录)需配合 afterCompletion
AOPSpring 代理层方法级横切(日志、事务)可通过 @AfterThrowing 处理
ExceptionHandlerSpring MVC统一错误响应仅 Controller 层异常

八、实际应用建议

8.1 Filter 适用场景

  • 跨系统通用逻辑(OAuth 认证、请求日志)
  • 编码处理、跨域设置
  • 安全过滤(XSS 防护)

8.2 Interceptor 适用场景

  • 业务无关的请求拦截(登录状态、Token 校验)
  • 请求级数据绑定
  • 性能日志

8.3 AOP 适用场景

  • 方法级日志记录
  • 事务管理
  • 性能监控
  • 缓存处理

8.4 ExceptionHandler 适用场景

  • 统一的错误响应格式
  • 业务异常转换
  • 全局异常日志

8.5 执行顺序选择原则

Filter(最外层)→ 处理跨系统通用逻辑
    ↓
Interceptor(请求级)→ 处理业务无关的请求拦截
    ↓
AOP(方法级)→ 处理细粒度横切关注点
    ↓
Controller(业务逻辑)

原则:从外到内,职责粒度从粗到细。


九、总结

执行阶段组件原理
请求预处理Filter → Interceptor preHandle → AOP @BeforeServlet 规范 + DispatcherServlet 调度 + 代理模式
业务处理Controller实际业务逻辑
请求后处理AOP @After → Interceptor postHandle → Filter代理模式 + 逆向执行
异常处理ExceptionHandlerSpring MVC 统一异常处理机制
最终清理Interceptor afterCompletion无论成功或失败都执行

核心原理

  1. Filter 最外层:由 Servlet 容器(Tomcat/Jetty)决定,独立于 Spring 生态
  2. Interceptor 在 DispatcherServlet 内部:由 Spring MVC 的 doDispatch() 方法调度
  3. AOP 在 Controller 层:基于 Spring 代理模式,在方法级别生效
  4. ExceptionHandler 兜底:处理 Controller 层异常,提供统一响应

理解这个链路,对于设计请求处理流程、排查问题、优化性能都至关重要。


如果对你有帮助,欢迎点赞、收藏!有任何问题欢迎留言讨论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值