【问题标题】:RequestContextHolder.getRequestAttributes() getting null after @AsyncRequestContextHolder.getRequestAttributes() 在@Async 之后为空
【发布时间】:2019-01-29 03:23:51
【问题描述】:

我们将@Async 用于多线程。直到每个多线程方法我都可以看到 RequestContextHolder.getRequestAttributes() 的值。

但是当我在方法内部进行调试时,我将请求属性设置为 NULL。

有什么想法吗?

【问题讨论】:

标签: java spring multithreading asynchronous


【解决方案1】:

为了解决这个问题,我们创建了一个 ContextAwareRunnable 对象,该对象预先填充了当前的 requestHolder、securityContextHolder 等,以便所有生成的线程都能够像在主线程中运行一样执行。

【讨论】:

  • 丹,你能详细说明一下吗?另外,我可以知道为什么一旦 Async 方法启动 RequestAttributes 就会消失(是因为新创建的线程)吗?谢谢!
  • @universe - 是的,新线程尚未填充来自主线程的任何请求详细信息。
  • 如果您需要这些详细信息,我会从 ExecutorService 运行方法调用,而不是标记方法 @Async。
  • 谢谢。但是,我认为我不能更改方法调用(这将是一个重大变化)。无论如何,我们可以在@Async 之前将这些请求详细信息设置为所有生成的线程吗?
  • 为什么你不能改变你的方法被调用的方式。就像一行代码一样简单executor.submit(() -> YourClass.methodName(), contextAwareExecutor);
【解决方案2】:

默认情况下,ThreadLocal 变量用作请求属性的持有者。这意味着只有处理整个 https 请求的单个线程才能访问请求属性。相比之下,@Async 方法由来自单独线程池的线程处理,因此它们无法访问属性。

但是,还有一个InheritableThreadLocal 变量可以用作请求属性持有者,而不是默认变量。您可以通过在DispatcherServletRequestContextFilter 中将threadContextInheritable 属性设置为true 来启用它。

查看RequestContextHolder 的实现以了解更多详细信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-17
    • 2020-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多