【问题标题】:Is RequestContextHolder thread-safe?RequestContextHolder 是线程安全的吗?
【发布时间】:2016-08-24 07:30:50
【问题描述】:

在我的 spring-jdbc 项目中,我有一个名为 DBStuff 的类,我用它来连接数据库并进行简单的数据库操作。这是一个网络项目,有用户,所以我很自然地使用会话机制。当我需要在DBStuff 类中检索请求数据时,我使用下面这行代码:

HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

但是,没有说明RequestContextHolder 是否是线程安全的。即使是春季的官方forum 也没有答案。由于使用 servlet,我需要为用户提供线程安全的特性。

根据定义,RequestContextHolder 被定义为“以线程绑定RequestAttributes 对象的形式公开 Web 请求的持有者类。”但我不确定“线程绑定”是否代表线程安全。

【问题讨论】:

  • 它是线程安全的,但是为什么要将数据访问层绑定到 Web 层...这是代码异味,恕我直言,这是您做错事的信号。
  • 我的 DataAccess 层和 Web 层是分开的,但每个用户请求都会保留其登录数据,这在 DB 操作中起着巨大的作用。我应该将 DataAccess 类更改为原型吗?但如果我这样做了,我的系统不会花费太多内存和性能吗?
  • 不,它们没有分开...您的数据层取决于 Web 层。你不能把你的 dbaccess 类放在一个不支持 web 的服务器中,因为它与 javax.servlet 和 Spring 的 web 相关包紧密耦合。因此,Web 和数据访问之间存在耦合。如果您需要它,可以在方法参数中传递这些内容,或者将其存储在 ThreadLocal 中,但不要在除网络绑定类之外的任何其他内容中泄露网络详细信息。

标签: java spring thread-safety


【解决方案1】:

“线程绑定”意味着每个线程都有自己的数据副本,因此它是线程安全的。

它为此使用ThreadLocal

private static final ThreadLocal<RequestAttributes> requestAttributesHolder = 
      new NamedThreadLocal<RequestAttributes>("Request attributes");

public static RequestAttributes getRequestAttributes() {
    RequestAttributes attributes = requestAttributesHolder.get();
    if (attributes == null) {
        attributes = inheritableRequestAttributesHolder.get();
    }
    return attributes;
}

requestAttributesHolder.get()为当前线程返回RequestAttributes,它是一个处理HTTP请求的线程。每个请求都有自己的线程。

ThreadLocal 的方法get() 使用映射将数据绑定到Thread.currentThread()

public T get() {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null)
            return (T)e.value;
    }
    return setInitialValue();
}

When and how should I use a ThreadLocal variable?

【讨论】:

  • 但是 DBStuff 类是单例的,这不是让 RequestContextHolder 绑定到这个类的线程吗?
  • 如果我有要求并在课堂上继续进行,这是真的。但问题是我试图在这个单例DBStuff 类中获取请求。如果RequestContextHolder绑定到当前线程,那么它如何处理两个同时的请求呢?
猜你喜欢
  • 2021-10-12
  • 2015-04-18
  • 2011-10-07
  • 2012-03-02
  • 2011-10-28
  • 2023-03-14
  • 2011-08-16
  • 2011-09-28
  • 2010-12-14
相关资源
最近更新 更多