39

If you use Spring, must your component classes (@Controller, @Service, @Repository) be thread safe? Or does Spring use them in a thread-safe manner so you don't have to worry about thread safety?

That is, if I have a @RequestMapping method in my @Controller, could that method be called simultaneously for the same controller object by more than one thread?

(This has sort-of been asked before, but not answered as such).

Raedwald
  • 46,613
  • 43
  • 151
  • 237
  • Regarding the edit. Spring will call the same method on the same `@Controller` class instance for a request with the same format required by `@RequestMapping`. – Sotirios Delimanolis May 28 '13 at 15:11

4 Answers4

57

Given

@Controller
public class MyController {
    @RequestMapping(value = "/index")
    public String respond() {
        return "index";
    }
}

Spring will create an instance of MyController. This is because Spring parses your configuration, <mvc:annotation-driven>, sees @Controller (which is like @Component) and instantiates the annotated class. Because it sees @RequestMapping as well, it generates a HandlerMapping for it, see the docs here.

Any HTTP requests the DispatcherServlet receives will be dispatched to this controller instance through the HandlerMapping registered before, calling respond() through java reflection on that instance.

If you have instance fields like

@Controller
public class MyController {
    private int count = 0;
    @RequestMapping(value = "/index")
    public String respond() {
        count++;
        return "index";
    }
}

count would be a hazard, because it might be modified by many threads and changes to it might be lost.

You need to understand how Servlet containers work. The container instantiates one instance of your Spring MVC DispatcherServlet. The container also manages a pool of Threads which it uses to respond to connections, ie. HTTP requests. When such a request arrives, the container picks a Thread from the pool and, within that Thread, executes the service() method on the DispatcherServlet which dispatches to the correct @Controller instance that Spring registered for you (from your configuration).

So YES, Spring MVC classes must be thread safe. You can do this by playing with different scopes for your class instance fields or just having local variables instead. Failing that, you'll need to add appropriate synchronization around critical sections in your code.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
1

By default, controllers are singletons and thus must be thread-safe. However, you can configure the controllers to be request or session scoped, i.e.:

@Controller
@Scope("session")
public class MyController {

    ...
}

Controllers with session scope can be helpful for managing session state. A good description of different patterns can be found in Using Sessions in Spring-MVC (including "scoped-proxies") and in How to get Session Object In Spring MVC. Some of the presented patterns require request scope.

The request scope is useful as well if you have data that you cannot afford to calculate more than one per request.

Codo
  • 75,595
  • 17
  • 168
  • 206
  • Hello. I came here and found this useful. But can You tell me, if there are lot of users say some hundreds or thousand. Does that mean we will have that many number of controllers? please help! @codo – Tahir Hussain Mir Dec 24 '16 at 09:03
  • 1
    I guess so. Otherwise it wouldn't work. If you need session data, you'll inevitably end up with data structures per user in memory. – Codo Dec 25 '16 at 13:06
  • Session-scoped beans should still be thread-safe (as required) as it is possible to have multiple requests at once being processed within a single session. – Donal Fellows Jun 28 '22 at 13:43
0

Yes, of course.

It's best if those are stateless, which makes them thread safe by default. If there's no shared, mutable state there's no problem.

duffymo
  • 305,152
  • 44
  • 369
  • 561
  • 7
    "of course": I don't think that is so obvious to a beginner. Care to expand a little? – Raedwald May 28 '13 at 15:08
  • @Raedwalk Spring only creates one instance (by default) of your `@Component` classes, so all of their instance fields will be shared for each request. – Sotirios Delimanolis May 28 '13 at 15:08
  • Few days ago, I saw opposite response from one of the experienced SO contributor. Response was, "each request will have its own instance of these components" (Different from HTTPServlet architecture). I agree "It's best if those are stateless, which makes them thread safe by default", but it would be great if there is any official documentation on "one instance of component". – kosa May 28 '13 at 15:09
  • 1
    Spring makes beans singletons by default, but there are other scopes as well: prototype, per request, per session. Other experienced developers might have made a different choice. I prefer stateless singletons because I think they scale better. – duffymo May 28 '13 at 15:21
  • 1
    "If there's no shared, mutable state" almost all interesting web-applications have shared, mutable data. In most cases, the shared data is in a data-base, so the work of ensuring thread-safety is done in Hibernate/ the JPA. – Raedwald May 28 '13 at 15:25
  • @Raedwald You'll have shared Service or Repository classes like DAOs to do database operations, but anything done in their methods will either be ThreadLocal or will use local instances within methods, so you won't have that problem. – Sotirios Delimanolis May 28 '13 at 15:31
  • 1
    Most interesting web applications don't have shared state. They keep session specific information safe in session, where only a particular user can see it. I don't think you understand what thread safety means. – duffymo May 28 '13 at 15:34
-1

A Spring component, as well as another class, must be thread-safe if it can be used concurrently by a number of threads. A Spring component is a singleton by default and can be called from different threads. From this point of view, its STATE should be thread-safe. From another hand, singleton Spring beans, normally serve requests in a call stack of a thread from a pool of thread. Normally a Spring component has fields, which values are injected interfaces or properties. The only need to take care of safety is the case when state objects are kept in a bean. Usually, it is not used due to servers are load-balanced and a state is kept in a cache or in a database. Singleton bean, thus, should be used as a set of functions, which transfers data as arguments of a related method, and its fields should not keep business data, but just injected beans, which serve call progress. Spring's controller is an example. Its methods are called by a Tomcat's threads, way of controllers methods mapping, and all the calls stack is done in one thread. Controller's method calls DAO methods and returns results in the same thread. A Session normally is persisted from session to session and this is handled by Spring. So, except for rare cases, there is no need to take care of thread safety.

Simon
  • 130
  • 1
  • 5