[ACCEPTED]-Should I put my ThreadLocals in a spring-injected singleton?-dependency-injection

Accepted answer
Score: 22

As @axtavt mentioned, request-scoped beans are usually a cleaner 36 and more elegant alternative to ThreadLocals 35 when you're talking about web applications. In 34 fact, under the covers, Spring implements 33 request-scoped beans using its own ThreadLocal 32 variables (see RequestContextHolder). Both ThreadLocal and scoped 31 beans give you the same basic advantage 30 - the ability to access the object without 29 having to pass it down manually through 28 the call stack.

There is one scenario where 27 ThreadLocal variales win over scoped beans, though, which 26 is in cases where you want to access the 25 object from outside of Spring's bean lifecycle. A 24 good example of this is inside a JSP taglib. Taglib 23 instances are controlled by the servlet 22 container, not Spring, and so cannot participate 21 in Spring's IoC framework, and so cannot 20 be wired up with a request-scoped bean (or 19 any other bean, for that matter). They can, however, access 18 ThreadLocal variables. There are ways around 17 this, but sometimes ThreadLocals are the 16 easiest approach.

One of the functional disadvantages 15 of ThreadLocal is that they're not very 14 useful in applications where data is passed 13 from thread to thread (InheritableThreadLocal 12 helps here sometimes, but not always). In 11 such situations, Spring's scoped beans also 10 fail, since they are implemented using ThreadLocal.

So 9 to advise on an approach, if you have a 8 Spring webapp, with Spring beans that want 7 access to objects that are specific to the 6 current request thread, then I'd advise 5 using request-scoped beans. If you need 4 to access those objects beyond the control 3 of Spring's beans, then ThreadLocal may 2 be easier, although I'd try to make things 1 work with scoped beans as much as possible.

Score: 13

If you use Spring, you can simply use a 2 request-scoped bean instead of explicit 1 ThreadLocals:

public interface UserName {
    ...
}

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

Spring uses ThreadLocals internally, and there is nothing 6 wrong with having them as infrastructure. However, you should 5 avoid them for business logic.

If you really need them, and 4 the request scope doesn't suit you (for some unforeseeable 3 reason), then I'd advice defining a custom 2 Scope, using ThreadLocal internally, thus hiding it from 1 your business-logic.

Score: 1

ThreadLocals work great when you have common 13 code that is handled by JMS, Queues and 12 http requests. Request scoped values do 11 not work in all the scenarios.

One important 10 thing to remember when using threadLocals 9 is that threads will be re-used by the server container, so are 8 the local variable values if something is 7 set on it, if you have values that needs 6 to be reset, use servlet filters/AOP proxy 5 objects on the controllers/jms listeners 4 to clear the values just before it invokes 3 the business logic, or else you could end 2 up debugging very hard to reproduce type 1 of issues .

More Related questions