RequestContextHolder是线程安全的吗?

时间:2016-04-29 08:21:45

标签: java spring thread-safety

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

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

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

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

1 个答案:

答案 0 :(得分:6)

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

它使用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请求的线程。每个请求都有自己的线程。

get()的方法ThreadLocal使用地图将数据绑定到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?