Spring offers multiple approaches to create beans and manage their lifecycles, referred to as scopes in the Spring world. In this article, we will delve into two common scopes you often encounter in Spring applications: singleton and prototype.
Singleton is the default scope for a bean in Spring. And now, we will start with Singleton.
Singleton Bean Scope
The singleton bean scope defines Spring’s default approach to managing beans in the context. It is also the most common bean scope you will encounter in production applications.
The Singleton Bean Scope in Spring refers to a configuration that specifies that a single instance of a bean will be created and shared throughout the entire application context. In other words, regardless of how many times you request the creation of a bean within the application context, Spring will return the same instance of that bean for each request. This ensures that there is only one instance of the bean in the application, making it a global and shared resource.
How Does Singleton Bean Work?
Let’s start our section on how Spring manages Singleton scoped beans. Especially since Singleton scope is the default (and most commonly used) bean scope in Spring, you need to understand what to expect when using this scope. In this section, I’ll explain the connection between the code you write and the Spring Context to facilitate the understanding of Spring’s behavior. Later, we’ll test this behavior with a few examples.
When Spring loads its context and assigns a name (sometimes referred to as the bean ID) to a bean, it creates a singleton bean. We call this scope ‘singleton’ because you always obtain the same instance when referring to a specific bean. However, be cautious! If beans have different names, you can have more than one instance of the same type in the Spring Context.
A singleton class in an application refers to a class that provides only one instance to the application and manages the creation of that instance. However, in Spring, a singleton doesn’t mean that the context has only one instance of this type. It means that an instance is assigned to a name, and this same instance will be referenced by that name consistently.
Is Singleton Thread Safe?
So far, we have discussed how Spring manages singleton beans. Now it’s time to discuss what you should be careful about when working with singleton beans. Let’s start by considering some scenarios where you should or shouldn’t use singleton beans.
The most important thing to consider with the singleton bean scope is that these beans need to be immutable since they assume that multiple components of the application can share a single instance of an object. In many real-world applications, multiple threads execute actions (for instance, in a web application). In such a scenario, multiple threads share the same object instance. If these threads modify the instance, you encounter a race condition scenario.
When multiple threads access a single bean, they are accessing the same instance. If these threads try to modify the instance simultaneously, they encounter a race condition issue. If a bean is not designed for concurrency, a race condition can lead to unexpected outcomes or exception situations.
A race condition occurs in multi-threaded architectures where multiple threads attempt to modify a shared resource. In a race condition scenario, the developer needs to properly synchronize the threads to prevent unexpected execution results or errors.
If you want mutable singleton beans, you have to make these beans concurrent yourself (especially using thread synchronization). However, singleton beans are not designed for synchronization. They are more often used to define the main design of an application and delegate responsibilities to each other. While synchronization is technically possible, it’s not a good practice because concurrency can significantly affect the performance of an application.
Prototype Bean Scope
The prototype bean scope is one of the bean scopes provided by the Spring Framework for managing beans. In contrast to the singleton scope, where a single instance of a bean is shared across the entire application context, the prototype scope creates a new instance of a bean every time it is requested from the Spring container.
Here’s a breakdown of how the prototype bean scope works:
- Creation of New Instances: When a bean with a prototype scope is requested, Spring creates a new instance of that bean each time. This means that every time you call for a bean, you get a completely new object with its own memory space.
- Lifecycle Management: Spring does not manage the lifecycle of prototype beans beyond their creation. It does not keep track of these instances, and thus, it does not perform operations like initialization and destruction on them automatically.
- Dependency Injection: Dependencies of prototype beans are injected when the bean is requested, and they are not managed by Spring’s container after that.
- Usage Scenarios: Prototype scope is suitable for beans that have state and need a new instance every time, like session-specific data or stateful components.
- Thread Safety: Since each instance of a prototype bean is unique, they are generally safe to use in a multi-threaded environment. However, it’s important to ensure that any shared dependencies injected into prototype beans are themselves thread-safe.
In summary, prototype beans are used when you want to create a new instance of a bean every time it is requested, which is particularly useful for stateful components or scenarios where each object instance should maintain its own separate state. However, managing the lifecycle and dependencies of prototype beans is the responsibility of the developer, as Spring’s container only creates new instances and does not track or manage them beyond that.
In this topic, we discussed the concept of Spring bean scopes, which determine how Spring manages the lifecycle and instances of beans within an application. Two common scopes, singleton and prototype, were highlighted.
- Singleton Scope: Singleton is the default scope in Spring and ensures that only one instance of a bean exists within the entire application context. This scope is suitable for stateless and shared beans. However, it’s important to be cautious with singleton beans in a multi-threaded environment to avoid race conditions.
- Prototype Scope: Prototype scope creates a new instance of a bean every time it’s requested from the container. This is useful when beans need to maintain their state separately for each usage. Spring does not manage prototype beans beyond their creation, making them more suitable for scenarios where instances need to be unique and stateful.
In both scopes, the developer should consider the application’s requirements, thread safety, and whether a shared or unique instance is needed. Singleton is common for stateless beans, while prototype is used when a new instance is desired for every request. Understanding these scopes helps developers design more efficient and reliable Spring applications.