Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Must Spring component classes be thread-safe

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).

like image 748
Raedwald Avatar asked May 28 '13 14:05

Raedwald


People also ask

Are Spring components thread-safe?

No spring object is not thread safe .

Which class is not thread-safe?

When designing a class that may be used for concurrent programming—that is, a class whose instances may be used by more than one thread at a time—it is imperative that you make sure the class is " thread-safe.” Consider the IntList class of Example 2-7. This class is not thread safe.

Are classes thread-safe?

A thread-safe class is a class that guarantees the internal state of the class as well as returned values from methods, are correct while invoked concurrently from multiple threads. The collection classes that are thread-safe in Java are Stack, Vector, Properties, Hashtable, etc.

Is Spring dependency injection thread-safe?

You should not worry about thread safety of the dependency injection, Spring does (most likely, spring is going to use just one thread to inject all the dependencies).


1 Answers

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.

like image 114
Sotirios Delimanolis Avatar answered Sep 28 '22 00:09

Sotirios Delimanolis