流程控制应通过责任链模式将“判断谁、拦什么、怎么回”解耦为身份识别→路径匹配→响应生成三步,每步职责单一、可测可替;切面按标准化路径顺序驱动,支持开关、白名单与日志追踪,并严守路径标准化、上下文初始化、处理器轻量及明确出口四条底线。

流程控制不是写一堆 if-else,而是把“判断谁、拦什么、怎么回”这三步串成一条清晰、可替换、不耦合的执行链。关键不在控制语句本身,而在每一步的责任边界是否明确。
用责任链模式组织校验步骤
把未认证拦截拆成三个独立环节:身份识别 → 路径匹配 → 响应生成。每个环节只做一件事,且能单独测试或替换:
- 身份识别层:统一调用 AuthenticationContext.isAuthenticated(),不查 session、不解析 token,只问“当前有没有人”
- 路径匹配层:根据请求 URI 查 Set<String> SECURE_PATHS,支持精确匹配或前缀匹配(如 "/api/"),不走正则、不遍历 List
- 响应生成层:调用 AuthFailureHandler.handle(request, response),具体返回 401 JSON、跳转登录页还是弹窗提示,由实现类决定
在切面中用顺序逻辑驱动流程
切面本身不写业务逻辑,只按固定顺序触发各环节,失败即中断:
- 先取当前请求路径,标准化为小写、去尾斜杠(如 "/API/User/" → "/api/user")
- 再查该路径是否在受保护集合中:SECURE_PATHS.contains(path)
- 若命中,立即调用 context.isAuthenticated();返回 false 就交由 handler 处理,不再执行原方法
- 全程无嵌套 if,用短路逻辑控制流向,比如:if (!paths.contains(path) || context.isAuthenticated()) { return joinPoint.proceed(); }
让流程可开关、可绕过、可调试
真实场景需要灰度、调试和例外处理,流程控制必须支持动态干预:
- 加一个全局开关配置:auth.enabled=true/false,关闭时直接放行,便于压测或紧急降级
- 白名单路径优先判断:PUBLIC_PATHS.contains(path),命中就跳过全部校验
- 记录日志时只打关键节点:“路径 /api/order 匹配受保护列表,但用户未登录,交由 JsonHandler 处理”,不记中间变量
避免流程失控的几个硬约束
流程越简单越可靠,但必须守住几条底线:
- 路径标准化必须前置——参数、大小写、斜杠差异都会导致 Set 匹配失效
- AuthenticationContext 必须在 Filter 阶段初始化完毕,不能等到切面里才首次解析
- AuthFailureHandler 的实现不能依赖数据库或远程调用,否则拦截本身变成性能瓶颈
- 所有流程分支最终都要有明确出口:放行、拦截、抛异常,不能隐式静默

















