Spring Boot 中上下文绑定必须在 Web 层 HandlerInterceptor 的 preHandle() 中完成,因代理无法感知 HTTP 请求上下文;Service 层通过静态工具类 UserContext 安全获取,@Async 需手动传递上下文;Filter、Interceptor、AOP 各司其职,不可混淆。

Spring Boot 中没有“Proxy 拦截器”这一标准概念。你提到的可能是对 代理(Proxy)、拦截器(Interceptor) 和 上下文绑定(Context Binding) 三者混合使用的实践需求,常见于:用 AOP 实现代理增强 + 在拦截逻辑中绑定用户/租户等请求上下文,以便业务层任意位置安全获取。
为什么不能直接在 Proxy 中做上下文绑定
Spring 的 JDK 动态代理或 CGLIB 代理作用于 Service 层方法调用,而用户身份、请求头、租户信息等通常只存在于 HTTP 请求生命周期中(即 Servlet 线程内)。代理本身不持有 request/response,也无法自动感知 Web 层上下文 —— 所以单纯靠 @Aspect 或 @Around 做上下文绑定是不可靠甚至失效的。
真正可行的上下文绑定时机在 Web 层拦截器
必须在请求刚进入 Web 容器、尚未分发到 Controller 时完成上下文初始化。这是唯一能稳定拿到 HttpServletRequest、解析 Token、提取用户/公司编码等信息的阶段。
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 使用
HandlerInterceptor.preHandle()解析 Authorization 头、校验 JWT、查 Redis 获取用户对象 - 将用户对象存入
FastThreadLocal<User>(比原生 ThreadLocal 更防内存泄漏) - 同时设置
Request.setAttribute("currentUser", user),供 Controller 中通过参数注入或 RequestContextHolder 获取 - 务必在
afterCompletion()中调用FastThreadLocal.remove(),避免线程复用导致上下文污染
Service 层如何安全使用上下文
不要在 Service 方法参数里硬塞 User 对象,也不建议每个方法都传参。推荐两种轻量级方案:
-
静态工具类访问:如
UserContext.getCurrentUser(),底层调用FastThreadLocal.get(),零侵入、任意位置可用 -
@Async 场景需手动传递:异步线程不共享主线程的 FastThreadLocal,需在提交任务前显式捕获并传入,例如:
asyncTaskExecutor.submit(() -> { UserContext.setUser(currentUser); doWork(); UserContext.remove(); });
别混淆 Filter、Interceptor 和 AOP 的职责边界
它们不是替代关系,而是分层协作:
- Filter:最外层,处理编码、跨域、原始请求日志,无法依赖 Spring Bean
- Interceptor:Web 层专属,可注入 RedisTemplate、UserService,适合做登录校验、上下文绑定、耗时统计
- AOP:Service 层增强,适合审计日志、事务控制、性能埋点,但不能用于首次构建用户上下文
不复杂但容易忽略:上下文必须在 Interceptor 中初始化,在 AOP 中只能消费,不能反向依赖。

















