Singleton vs Prototype Scope in Spring Boot: Key Differences and Usage
singleton scope means one shared instance of a bean per Spring container, while prototype scope creates a new instance every time the bean is requested. Singleton beans are reused and managed by Spring, but prototype beans are created fresh and not fully managed after creation.Quick Comparison
This table summarizes the main differences between singleton and prototype scopes in Spring Boot.
| Aspect | Singleton Scope | Prototype Scope |
|---|---|---|
| Instance Count | One shared instance per Spring container | New instance created on each request |
| Lifecycle Management | Fully managed by Spring container | Created and handed off; Spring does not manage complete lifecycle |
| Use Case | Stateless, shared services or components | Stateful or short-lived objects |
| Performance | Better for reuse, less memory overhead | More memory and CPU due to frequent creation |
| Dependency Injection | Injected once and reused | Injected fresh each time requested |
| Default Scope | Yes, default scope in Spring | No, must be explicitly declared |
Key Differences
The singleton scope in Spring Boot means that the Spring container creates exactly one instance of the bean, and all requests for that bean return the same instance. This is efficient for stateless services or components that can be safely shared across the application.
In contrast, the prototype scope creates a new bean instance every time it is requested from the container. This is useful when you need independent instances with their own state, such as form objects or temporary data holders.
Another important difference is lifecycle management: Spring fully manages the lifecycle of singleton beans, including initialization and destruction callbacks. For prototype beans, Spring creates and initializes them but does not manage their full lifecycle, so destruction callbacks are not called automatically.
Code Comparison
import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component @Scope("singleton") public class MyService { public String getMessage() { return "Hello from Singleton"; } } // Usage in another component @Component public class Client { private final MyService myService; public Client(MyService myService) { this.myService = myService; } public void showMessage() { System.out.println(myService.getMessage()); } }
Prototype Equivalent
import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component @Scope("prototype") public class MyService { public String getMessage() { return "Hello from Prototype"; } } // Usage in another component @Component public class Client { private final ApplicationContext context; public Client(ApplicationContext context) { this.context = context; } public void showMessage() { MyService myService1 = context.getBean(MyService.class); MyService myService2 = context.getBean(MyService.class); System.out.println(myService1.getMessage()); System.out.println(myService2.getMessage()); System.out.println("Are instances equal? " + (myService1 == myService2)); } }
When to Use Which
Choose singleton scope when you want a single shared instance for stateless services, configuration, or components that do not hold user-specific data. This improves performance and memory usage by reusing the same object.
Choose prototype scope when you need a new instance every time, such as for stateful beans, user session data, or objects that should not be shared. This ensures each use gets a fresh object without shared state.
Remember that prototype beans require manual lifecycle management if you need cleanup, as Spring does not handle their destruction automatically.