Spring 中获取当前 HttpServletRequest 的方法详解
在 Spring(尤其是 Spring MVC)应用中,经常需要在非 Controller 层(如 Service、工具类)获取当前请求的 HttpServletRequest 对象(如获取请求头、客户端 IP、参数等)。核心解决方案是利用 RequestContextHolder 工具类,它通过 ThreadLocal 存储当前请求上下文,确保线程安全。从 “原理→使用方式→注意事项→扩展场景” 四个维度,彻底讲透如何安全、高效地获取 HttpServletRequest。
核心原理:RequestContextHolder 与 ThreadLocal
RequestContextHolder 是 Spring 提供的请求上下文持有者,其底层通过 ThreadLocal 存储当前线程的请求上下文(RequestAttributes),确保每个线程只能访问自己的请求对象,避免多线程环境下的资源竞争。
1. 关键类与接口关系
graph LR
A[RequestContextHolder] --> B[ThreadLocal]
B --> C[ServletRequestAttributes]
C --> D[HttpServletRequest]
C --> E[HttpServletResponse]
RequestContextHolder:静态工具类,提供 currentRequestAttributes() 方法获取当前线程的 RequestAttributes;
RequestAttributes:请求属性接口,定义了获取请求 / 会话属性的方法,其实现类 ServletRequestAttributes 封装了 HttpServletRequest 和 HttpServletResponse;
ThreadLocal:线程局部变量,确保每个线程的 RequestAttributes 独立存储,互不干扰。
2. 上下文存储时机
Spring MVC 在请求进入时(DispatcherServlet 处理请求的初期),会自动将当前 HttpServletRequest 封装为 ServletRequestAttributes,并通过 RequestContextHolder.setRequestAttributes() 存入 ThreadLocal;请求结束后,会清除 ThreadLocal 中的数据,避免内存泄漏。
核心流程简化: