我是否应该将ThreadLocals放入弹簧注入的单例中?


问题内容

一些人(例如,在服务器端http://www.theserverside.com/news/thread.tss?thread_id=41473)建议使用ThreadLocal对象与使用全局变量一样糟糕。我想如果您将它们设为公共静态变量,那是真的。然后的问题是,很难分辨出它的使用位置,更改位置等。

在我的spring DI tomcat
Web应用程序中,如果我只是让spring创建一个包含ThreadLocal的单例对象,然后将该单例注入需要它的任何类中,似乎可以解决此问题。

所以我的单身看起来像这样:

@Component
public class Username {
    private ThreadLocal<String> username;

    public Username() {
        username = new ThreadLocal<String>();
    }

    public String getUsername()
        return username.get();
    }

    public void setUsername(String name) {
        username.set(name);
    }
}

可能需要的类如下所示:

@Service
public class addEntryTransaction {

    @Autowired
    Username username;

    public void method() {
        ...
        log("Method called by "+username.getUsername());
        ...
     }

}

这样做仍然具有不必通过多个无关的层传递用户名的好处,从而使方法参数更简单。@Autowired是该类使用该变量的声明。

这种方法的优点和缺点是什么?


问题答案:

如果使用Spring,则可以简单地使用请求范围的bean而不是显式ThreadLocals:

public interface UserName {
    ...
}

@Component 
@Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
public class UsernameImpl implements UserName { 
    private String username; 
    ...
}