As @axtavt mentioned, request-scoped beans are usually a cleaner and more elegant alternative to ThreadLocals when you're talking about web applications. In fact, under the covers, Spring implements request-scoped beans using its own ThreadLocal variables (see RequestContextHolder
). Both ThreadLocal and scoped beans give you the same basic advantage - the ability to access the object without having to pass it down manually through the call stack.
There is one scenario where ThreadLocal variales win over scoped beans, though, which is in cases where you want to access the object from outside of Spring's bean lifecycle. A good example of this is inside a JSP taglib. Taglib instances are controlled by the servlet container, not Spring, and so cannot participate in Spring's IoC framework, and so cannot be wired up with a request-scoped bean (or any other bean, for that matter). They can, however, access ThreadLocal variables. There are ways around this, but sometimes ThreadLocals are the easiest approach.
One of the functional disadvantages of ThreadLocal is that they're not very useful in applications where data is passed from thread to thread (InheritableThreadLocal helps here sometimes, but not always). In such situations, Spring's scoped beans also fail, since they are implemented using ThreadLocal.
So to advise on an approach, if you have a Spring webapp, with Spring beans that want access to objects that are specific to the current request thread, then I'd advise using request-scoped beans. If you need to access those objects beyond the control of Spring's beans, then ThreadLocal may be easier, although I'd try to make things work with scoped beans as much as possible.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…