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

一、流程总览

该流程图描述了一个多层拦截器链的业务处理流程,核心逻辑为:

  1. 前置拦截 :通过 predHandler1predHandler2 逐层校验请求合法性。
  2. 核心处理 :通过校验后执行核心业务逻辑 handler()
  3. 后置处理与清理:按反向顺序执行后置操作,最终完成资源释放。

二、模块功能与业务场景
1. 前置拦截模块
  • predHandler1()
    • 业务作用:执行第一层基础校验(如用户身份验证、请求合法性检查)。
    • 逻辑分支
      • **返回 **false:请求非法或校验失败,直接终止流程(如用户未登录时返回401错误)。
      • **返回 **true:进入下一层校验 predHandler2()
  • predHandler2()
    • 业务作用:执行第二层精细化校验(如权限校验、参数合规性验证)。
    • 逻辑分支
      • **返回 **false:校验失败,仅触发 afterCompletion1()(如记录失败日志),流程终止。
      • **返回 **true:进入核心业务处理 handler()

2. 核心业务模块
  • handler()
    • 业务作用:执行实际业务逻辑(如数据计算、数据库操作、服务调用)。
    • 触发条件 :所有前置拦截器均通过(predHandler1predHandler2 均返回 true)。

3. 后置处理模块
  • postHandler2()
    • 业务作用:内层后置操作(如修改响应数据、记录操作日志)。
    • 执行顺序 :优先于外层后置操作(postHandler1()),确保依赖资源可用。
  • postHandler1()
    • 业务作用:外层后置操作(如统计请求耗时、格式化最终响应)。

4. 完成清理模块
  • afterCompletion1()
    • 业务作用:外层资源释放(如关闭数据库连接、清理临时文件)。
    • 触发条件 :只要 predHandler1 返回 true,无论后续流程是否成功,均会执行。
  • afterCompletion2()
    • 业务作用:内层资源释放(如提交事务、关闭内层连接)。
    • 触发条件predHandler2 返回 true 且流程执行到 handler() 后。

三、流程分支详解
分支 1: predHandler1** 返回 **false
  • 路径predHandler1 → 直接响应
  • 业务意义:基础校验失败,无需后续处理(如用户未登录时直接拒绝请求)。
分支 2: predHandler2** 返回 **false
  • 路径predHandler1 → predHandler2 → afterCompletion1
  • 业务意义:精细化校验失败(如用户无权限),但需释放外层资源(如记录失败日志)。
分支 3:所有拦截通过
  • 路径predHandler1 → predHandler2 → handler → postHandler2 → postHandler1 → afterCompletion2
  • 业务意义:完整处理请求,按反向顺序释放资源(如先提交事务,再关闭连接)。

四、流程设计的关键逻辑
  1. 前置顺序正向,后置顺序反向
    • 前置链 :由外到内逐层校验(predHandler1 → predHandler2),确保基础条件优先验证。
    • 后置链 :由内到外反向执行(postHandler2 → postHandler1),避免依赖资源提前释放。
  2. 资源释放的精准性
    • 外层资源 (如数据库连接)在 afterCompletion1 释放。
    • 内层资源 (如事务)在 afterCompletion2 释放,确保提交事务后再关闭连接。

五、实际应用场景
  1. API 请求校验链
    • predHandler1:验证 Token 有效性 → predHandler2:校验用户角色权限 → handler:返回数据。
    • 若角色权限不足,记录日志(afterCompletion1)并终止流程。
  2. 事务管理流程
    • predHandler1:打开数据库连接 → predHandler2:开启事务 → handler:执行业务 SQL。
    • postHandler2:提交事务 → postHandler1:关闭连接。
相关推荐
noravinsc17 分钟前
django admin AttributeError: ‘UserResorce‘ object has no attribute ‘ID‘
数据库·django·sqlite
极小狐3 小时前
如何使用极狐GitLab 的外部状态检查功能?
数据库·ci/cd·gitlab·devops·mcp
Leo.yuan4 小时前
数据仓库建设全解析!
大数据·数据库·数据仓库·数据分析·spark
闪电麦坤954 小时前
SQL:子查询(subqueries)
数据库·sql
活跃的煤矿打工人4 小时前
【星海出品】分布式存储数据库etcd
数据库·分布式·etcd
文牧之4 小时前
PostgreSQL的扩展 pgcrypto
运维·数据库·postgresql
老友@5 小时前
小集合 VS 大集合:MySQL 去重计数性能优化
数据库·mysql·性能优化
声声codeGrandMaster6 小时前
django之优化分页功能(利用参数共存及封装来实现)
数据库·后端·python·django
熏鱼的小迷弟Liu7 小时前
【Redis】Redis Zset实现原理:跳表+哈希表的精妙设计
数据库·redis·散列表