How do you implement the singleton pattern in Spring?

Table of Contents

Introduction

In software design, the Singleton pattern ensures that a class has only one instance and provides a global point of access to that instance. The Singleton pattern is a widely used design pattern, especially when you need to restrict the instantiation of a class to one object. In Spring, beans are typically singleton-scoped by default, meaning Spring's Inversion of Control (IoC) container will ensure that only one instance of a bean is created throughout the entire application context.

In this article, we'll explore how the Singleton pattern works in Spring, how Spring implements it, and how you can customize the behavior of singleton beans to suit your application's needs.

Singleton Pattern in Spring

1. Spring’s Default Bean Scope

By default, Spring beans are singleton-scoped, meaning that there will be only one instance of a bean in the Spring container. This instance is created during the initialization of the application context and is shared across the entire application. Spring manages the lifecycle of this singleton instance, and it is only instantiated once unless explicitly configured otherwise.

In Spring, the singleton pattern is implemented implicitly by the bean scope. This means that when you define a bean, unless specified otherwise, Spring treats it as a singleton bean.

2. How Spring Implements the Singleton Pattern

Spring's singleton scope ensures that a bean is instantiated only once in the container and is cached for future reference. Each time you request a bean from the application context, the same instance is returned.

  • Bean Definition: When you define a bean, Spring registers it in the application context (or IoC container).
  • Singleton Creation: The Spring container creates a single instance of the bean when the application context is created.
  • Shared Instance: This single instance is then shared across all components that request the bean.

3. Example of Singleton Bean in Spring

Java-based Configuration (Using @Bean)

In Java-based configuration, Spring’s default scope is singleton. You don’t need to specify the scope explicitly if you want to use the default singleton scope. Here’s an example:

In this example:

  • The **@Bean** annotation registers the MyService class as a Spring bean.
  • Since we don’t specify the scope, Spring will default to the singleton scope.

Accessing the Singleton Bean

When you request the MyService bean multiple times from the Spring context, it will return the same instance:

Output:

true

Customizing Singleton Behavior in Spring

While Spring uses the Singleton pattern by default, there are situations where you might want to configure the behavior of a singleton bean or ensure that it behaves in a specific way.

1. Lazy Initialization of Singleton Beans

By default, Spring creates singleton beans eagerly during application context initialization. However, you can use the lazy initialization feature to delay the creation of a singleton bean until it is actually requested.

Example of Lazy Initialization:

In this case, the MyService bean will only be instantiated when it is first requested, not during the context initialization.

2. Singleton with Constructor Injection

Spring's singleton beans are usually created using constructor injection or setter injection. In constructor injection, Spring will pass the dependencies when creating the singleton bean.

Example:

And the configuration class:

In this case, Spring will ensure that there is only one instance of MyService in the container, and it will inject the shared Dependency bean into the singleton MyService instance.

Advanced Singleton Use Cases

1. Singleton Bean with Custom Initialization and Destruction

In some cases, you might need to perform custom initialization or destruction tasks for your singleton bean. Spring provides two ways to specify custom initialization and destruction methods.

Example with Custom Methods:

Configuration with initMethod and destroyMethod:

In this example:

  • **initMethod**: This method is called after the bean has been initialized, but before it is used.
  • **destroyMethod**: This method is called before the bean is destroyed.

Singleton Pattern vs Other Bean Scopes in Spring

FeatureSingleton BeanPrototype BeanRequest BeanSession Bean
Instance per Application1 instance per containerNew instance each timeNew instance per HTTP requestNew instance per HTTP session
Default ScopeYes (default)NoNoNo
LifecycleManaged by Spring containerManaged by Spring containerManaged per HTTP requestManaged per HTTP session
UsageShared across the appIndependent, stateful beansWeb application contextWeb application context

Conclusion

In Spring, the Singleton pattern is implemented by default through the singleton scope of beans. A singleton-scoped bean ensures that only one instance of the bean is created and shared across the application. Spring handles the lifecycle of singleton beans, including initialization and destruction, and allows you to customize behaviors such as lazy initialization or custom methods.

While Spring defaults to singleton beans, it also allows flexibility through other bean scopes like prototype, request, and session for different use cases. Understanding how Spring manages the singleton scope is crucial for creating efficient, reusable beans in your application.

Similar Questions