RequestContextHolder是Spring提供的一个工具类,用于在多线程环境中存储和访问与当前线程相关的请求上下文信息。它主要用于将当前请求的信息存储在线程范围内,以便在不同的组件中共享和访问这些信息,特别是在没有直接传递参数的情况下。
1.源码解读
@Nullable
public static RequestAttributes getRequestAttributes() {
RequestAttributes attributes = (RequestAttributes)requestAttributesHolder.get();
if (attributes == null) {
attributes = (RequestAttributes)inheritableRequestAttributesHolder.get();
}
return attributes;
}
private static final ThreadLocal<RequestAttributes> requestAttributesHolder = new NamedThreadLocal("Request attributes");
private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder = new NamedInheritableThreadLocal("Request context");
// requestAttributesHolder.get()
// inheritableRequestAttributesHolder.get()
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
从中不难看出RequestContextHolder的底层逻辑是使用ThreadLocal实现的,因此我们不难理解为何RequestContextHolder可以用于在多线程环境中存储和访问与当前线程相关的请求上下文信息。
2.使用 RequestContextHolder
private static HttpServletRequest getHttpServletRequest() {
return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
}
3.其他HttpServletRequest获取方式
3.1 Controller中加参获取
@PostMapping("/xx")
public String addCustomer(HttpServletRequest request) {
// TODO
request..
return "SUCCESS";
}
3.2 自动注入
@Controller
public class DemoController{
@Resource
private HttpServletRequest request;
@RequestMapping("/test")
public String test(){
// TODO
request..
return "SUCCESS";
}
}