Spring Controller Scope: Singleton vs Prototype and Concurrency Safety
The article explains that Spring MVC controllers are singleton by default, which makes mutable instance fields unsafe for concurrent requests, demonstrates the issue with sample code, and shows how applying @Scope("prototype") or using ThreadLocal resolves the thread‑safety problem.
In Spring MVC, a @Controller bean is singleton by default, meaning a single instance handles all requests and any mutable instance fields are shared across threads, leading to concurrency hazards.
Example code illustrates a controller with an int num field that is incremented in two request‑mapping methods:
@Controller public class ScopeTestController { private int num = 0; @RequestMapping("/testScope") public void testScope() { System.out.println(++num); } @RequestMapping("/testScope2") public void testScope2() { System.out.println(++num); } }
When accessing /testScope the output is 1; a subsequent call to /testScope2 yields 2, demonstrating that the same controller instance is reused and the field is not thread‑safe.
Adding @Scope("prototype") changes the bean to prototype scope, creating a new controller instance for each request:
@Controller @Scope("prototype") public class ScopeTestController { private int num = 0; @RequestMapping("/testScope") public void testScope() { System.out.println(++num); } @RequestMapping("/testScope2") public void testScope2() { System.out.println(++num); } }
Now both /testScope and /testScope2 return 1, confirming that each request gets its own instance and the field is no longer shared.
Recommended solutions are: (1) avoid defining mutable member variables in controllers; (2) if a variable is necessary, declare the controller with prototype scope using @Scope("prototype") ; (3) alternatively, store per‑thread data with ThreadLocal .
Spring bean scopes include singleton, prototype, request, session, and global session, each providing different lifecycle and visibility characteristics.
Architect's Guide
Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.