MrJazsohanisharma

Spring Bean Scopes: Singleton vs Prototype

Blog ads

1. Introduction

In the Spring Framework, grasping the concept of bean scopes is essential for successful application development. The bean scope defines the lifecycle and visibility of a bean within the Spring container. In simple terms, it outlines how and when a bean is created, utilized, and destroyed. While there are various scopes in Spring, the two most frequently used are Singleton and Prototype. In this blog, we will delve into these two scopes, offering clear examples and practical use cases to help you understand their differences and applications.

2. Usages

Choosing the correct bean scope is essential for optimizing resource management and application performance. Here’s when to consider using each of these scopes:

  • Singleton: Use this scope when you need a single shared instance of a bean across the entire Spring container. It's the default scope in Spring. Singleton beans are ideal when:
    • You want to guarantee that there is only one shared instance for the whole application.
    • The bean is stateless or manages shared state with care.
  • Prototype: Use this scope when you want a new instance of a bean each time one is requested from the Spring container. Prototype beans are ideal when:
    • You require a mutable state in your beans, ensuring that each instance operates independently.
    • You are working with beans that hold specific contextual data relevant to each user or request.

3. Code Example

Let’s dive into a Spring Boot application to demonstrate how Singleton and Prototype scopes work in practice.

Step 1: Setting Up Spring Boot

Create a new Spring Boot project and include the necessary dependencies in your pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

Step 2: Create Singleton and Prototype Beans

Create two classes representing the Singleton and Prototype beans.

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("singleton")
public class SingletonBean {
    private String message = "I am a Singleton bean!" ;

    public String getMessage() {
        return message;
    }
}
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("prototype")
public class PrototypeBean {
    private String message = "I am a Prototype bean!";

    public String getMessage() {
        return message;
    }
}

Step 3: Create the Main Application Class

Let’s set up the main application class that utilizes both beans:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class BeanScopeDemoApplication implements CommandLineRunner {

    @Autowired
    private ApplicationContext context;

    public static void main(String[] args) {
        SpringApplication.run(BeanScopeDemoApplication.class, args);
    }

    @Override
    public void run(String... args) {
        SingletonBean singletonBean1 = context.getBean(SingletonBean.class);
        SingletonBean singletonBean2 = context.getBean(SingletonBean.class);
        System.out.println("Singleton Bean 1: " + singletonBean1.getMessage());
        System.out.println("Singleton Bean 2: " + singletonBean2.getMessage());
        System.out.println("Are Singleton Beans same instance? " + (singletonBean1 == singletonBean2));

        PrototypeBean prototypeBean1 = context.getBean(PrototypeBean.class);
        PrototypeBean prototypeBean2 = context.getBean(PrototypeBean.class);
        System.out.println("Prototype Bean 1: " + prototypeBean1.getMessage());
        System.out.println("Prototype Bean 2: " + prototypeBean2.getMessage());
        System.out.println("Are Prototype Beans same instance? " + (prototypeBean1 == prototypeBean2));
    }
}

Step 4: Run the Application

When you run the application, you should see output similar to this:

Singleton Bean 1: I am a Singleton bean!
Singleton Bean 2: I am a Singleton bean!
Are Singleton Beans same instance? true
Prototype Bean 1: I am a Prototype bean!
Prototype Bean 2: I am a Prototype bean!
Are Prototype Beans same instance? false

4. Explanation

In our example, we created two Spring beans, one with Singleton scope and the other with Prototype scope.

  • Singleton Bean: When you request a SingletonBean from the Spring context, you receive the same instance every time. This is clear from the output, as both singletonBean1 and singletonBean2 point to the same object in memory, which confirms their Singleton nature.
  • Prototype Bean: When you request PrototypeBean, a new instance is created each time you call context.getBean(PrototypeBean.class). In our example, prototypeBean1 and prototypeBean2 are distinct instances, as indicated by the result of their equality check being false.

5. Best Practices

To effectively utilize Singleton and Prototype bean scopes in your applications, keep these best practices in mind:

  • Use Singleton for Shared State: If your beans handle shared data without instance-specific variables, opting for Singleton is usually the best choice. However, steer clear of using Singleton for mutable state that may change over time without proper synchronization.
  • Avoid State in Singleton Beans: When working with Singleton beans, aim to keep them stateless whenever possible to avoid unintended side effects, particularly in concurrent environments.
  • Leverage Prototype for Stateful Beans: Choose Prototype when the bean needs to maintain state that is specific to a user session or transaction. This helps prevent conflicts and data leakage between different users or operations.
  • Beware of Resource Management: Be aware that Prototype beans are not automatically managed by Spring’s container upon creation. Make sure to properly handle the cleanup of any resources.

6. Conclusion

Grasping the concepts of Spring's bean scopes, especially Singleton and Prototype, is crucial for developing efficient and maintainable applications. By choosing the appropriate scope according to your application's specific requirements, you can enhance performance, improve resource management, and prevent potential problems in the future.

As you embark on your next Spring project, take the time to think about how bean scopes will influence your application's structure. Continue to experiment and learn, and you'll quickly become proficient in the intricacies of the Spring Framework.

ads

Previous Post Next Post