子線程獲取Request
有時候在進行業務處理時對于一些對于業務不那么重要且對于返回結果無關的情況會開啟一個新的線程進行處理,但是在開啟新線程進行處理時發現無法從RequestContextHolder中獲取到當前的請求,取出來是null
這是因為RequestContextHolder中的信息都是存儲在ThreadLocal中的,而ThreadLocal中的數據是使用線程進行查找的,不是該線程存儲的,是無法查找到的
private?static?final?ThreadLocal<RequestAttributes>?requestAttributesHolder?=
??????new?NamedThreadLocal<RequestAttributes>("Request?attributes");
private?static?final?ThreadLocal<RequestAttributes>?inheritableRequestAttributesHolder?=
??????new?NamedInheritableThreadLocal<RequestAttributes>("Request?context");
但是有時候子線程就是需要獲取到當前請求怎么辦呢?
此時就需要將RequestAttributes對象設置為子線程共享的,在開啟子線程之前
//?主線程先獲取到請求信息
RequestAttributes?requestAttributes?=?RequestContextHolder.getRequestAttributes();
//?設置子線程共享
RequestContextHolder.setRequestAttributes(requestAttributes,true);
這是什么原理?
public?static?void?setRequestAttributes(RequestAttributes?attributes,?boolean?inheritable)?{
???if?(attributes?==?null)?{
??????resetRequestAttributes();
???}
???else?{
??????if?(inheritable)?{??//?如果為true,則將信息存儲在inheritableRequestAttributesHolder中
?????????inheritableRequestAttributesHolder.set(attributes);
?????????requestAttributesHolder.remove();
??????}
??????else?{
?????????requestAttributesHolder.set(attributes);
?????????inheritableRequestAttributesHolder.remove();
??????}
???}
}
可以看到NamedInheritableThreadLocal重寫了getMap方法
ThreadLocalMap?getMap(Thread?t)?{
???return?t.inheritableThreadLocals;
}
https://zhhll.icu/2020/javaweb/問題/7.子線程獲取Request/
本文由 mdnice 多平臺發布