我们正在使用@Async进行多线程处理。直到每个多线程方法我都可以看到RequestContextHolder.getRequestAttributes()的值。但是当我在方法内部调试时,我得到的请求属性为NULL。有什么想法吗?
oprakyz71#
为了解决这个问题,我们创建了一个ContextAwareRunnable Object,它预先填充了当前的requestHolder、securityContextHolder等,这样所有派生的线程都可以像在主线程中运行一样执行。
ContextAwareRunnable
fiei3ece2#
默认情况下,ThreadLocal变量用作请求属性的保持器。这意味着只有处理整个https请求的单个线程才能访问请求属性。相比之下,@Async方法由来自单独线程池的线程处理,因此它们不能访问属性。但是还有一个InheritableThreadLocal变量可以用作请求属性的保持器,而不是默认值。您可以通过在DispatcherServlet或RequestContextFilter中将threadContextInheritable属性设置为true来启用它。查看RequestContextHolder的实现以了解更多细节。
ThreadLocal
@Async
InheritableThreadLocal
DispatcherServlet
RequestContextFilter
threadContextInheritable
true
RequestContextHolder
rjee0c153#
RequestContextHolder是请求绑定的(在本例中意味着线程绑定)。我已经使用这种 Package 器修复了空性问题:
private Executor wrap(Executor executor) { return task -> executor.execute(wrap(task)); } private Runnable wrap(Runnable task) { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); return () -> { try { RequestContextHolder.setRequestAttributes(requestAttributes); task.run(); } finally { RequestContextHolder.resetRequestAttributes(); } }; }
字符串
3条答案
按热度按时间oprakyz71#
为了解决这个问题,我们创建了一个
ContextAwareRunnable
Object,它预先填充了当前的requestHolder、securityContextHolder等,这样所有派生的线程都可以像在主线程中运行一样执行。fiei3ece2#
默认情况下,
ThreadLocal
变量用作请求属性的保持器。这意味着只有处理整个https请求的单个线程才能访问请求属性。相比之下,@Async
方法由来自单独线程池的线程处理,因此它们不能访问属性。但是还有一个
InheritableThreadLocal
变量可以用作请求属性的保持器,而不是默认值。您可以通过在DispatcherServlet
或RequestContextFilter
中将threadContextInheritable
属性设置为true
来启用它。查看
RequestContextHolder
的实现以了解更多细节。rjee0c153#
RequestContextHolder
是请求绑定的(在本例中意味着线程绑定)。我已经使用这种 Package 器修复了空性问题:字符串