Welcome to the next step in your journey through the Spring Framework. In our previous lesson, you learned how to programmatically define beans using @Configuration and @Bean, giving you full control over how objects are created and managed by the Spring container.
So far, whether we've used component scanning or Java-based configuration, we haven't specified how many instances of a bean should exist or how long they should live. This is governed by a bean's scope. Understanding bean scopes is fundamental to building robust enterprise applications, as it dictates how state is managed across your application.
This lesson focuses on configuring and differentiating between the two most essential bean scopes: singleton and prototype. We will explore what they are, when to use each, and how to configure them in your Spring application.
Let's begin with a high-level overview of these two core scopes.

1. The Singleton Scope: One Bean to Rule Them All
The singleton scope is the default and most common scope in Spring. When a bean is configured as a singleton, the Spring IoC container creates exactly one instance of that bean. Every time your application requests that bean—whether through dependency injection or a direct call to the application context—it will receive a reference to that same, single instance.
Key Characteristics:
- One Instance: Only one object instance is created per Spring container.
- Shared State: Any changes made to the bean's state are visible throughout the entire application, as all components are interacting with the same object. This makes singletons ideal for stateless components like services, repositories, and utility classes.
- Eager Initialization: By default, Spring creates all singleton beans when the application context starts up.
- Default Behavior: If you don't specify a scope for a bean, Spring automatically makes it a singleton.
This concept of a single, shared instance is very efficient. However, it requires careful design. Since your experience includes backend development with a MERN stack, you can think of singleton beans as being analogous to modules in Node.js that are cached by require()—once loaded, the same instance is returned on subsequent calls. This shared nature means you must be cautious about storing any user-specific or request-specific data in a singleton bean's fields, as it could lead to concurrency issues.
To understand how Spring handles singleton beans, let's watch a detailed demonstration.
Deep Dive into Spring Bean Scopes: Types and Uses Explained
The presenter in this CodeSnippet video provides an excellent walkthrough of the singleton scope, using application logs to show exactly what happens at startup.
Please watch the segment from Singleton scope explanation. Pay close attention to these points: The presenter confirms that singleton is the default scope. He analyzes the application startup logs to show that the beans are created eagerly (before any request is made). He uses hash codes to prove that the same bean instance is injected into multiple different components.
2. The Prototype Scope: A New Bean for Every Request
In contrast to the singleton scope, the prototype scope results in the creation of a new bean instance every time it is requested. The Spring container creates the bean, configures it, and hands it over to the client, but does not manage its subsequent lifecycle.
Key Characteristics:
- New Instance on Request: Every call to
context.getBean()or every injection into another bean will result in a brand-new object. - Stateful Objects: This scope is perfect for stateful beans, where each client needs its own independent copy. For example, a builder object that constructs a complex entity or a user-specific shopping cart object.
- Lazy Initialization: Prototype beans are only created when they are explicitly requested. They are not instantiated at application startup.
- Lifecycle Management: Spring does not manage the complete lifecycle of prototype beans. While it calls initialization lifecycle callbacks, it does not call destruction callbacks (like
@PreDestroy). It is the client's responsibility to clean up prototype-scoped beans if necessary.
Let's continue with the same video to see how prototype behavior differs from singleton.
Deep Dive into Spring Bean Scopes: Types and Uses Explained
Now, let's see how changing the scope to prototype completely alters the bean's lifecycle and instantiation.
Watch the segment covering the prototype scope from Prototype scope demonstration. Notice the following key differences: When the scope is changed to prototype, the application startup logs are much quieter because the beans are now initialized lazily. A new instance is created only when an API endpoint that requires the bean is hit. The hash codes confirm that each request for the bean results in a completely new object.
3. Configuring Scopes in Practice
You can define a bean's scope using the @Scope annotation. You can apply it to classes annotated with @Component (or its specializations) or to methods annotated with @Bean.
While you can use string literals like @Scope("singleton") or @Scope("prototype"), the recommended approach is to use the constants provided by the ConfigurableBeanFactory interface. This avoids typos and improves code readability.
ConfigurableBeanFactory.SCOPE_SINGLETONConfigurableBeanFactory.SCOPE_PROTOTYPE
The following video provides a clear, hands-on demonstration of creating both a singleton and a prototype bean in the same application and verifying their behavior. This will solidify everything we've discussed so far.
Spring & Spring Boot Annotations Series - #8 - @Scope Annotation | Singleton and Prototype Scopes
This Java Guides video offers a concise, side-by-side demonstration of configuring and testing singleton and prototype scopes.
Watch the initial overview of the two scopes: Singleton vs. Prototype. Follow along as the presenter sets up the code, creating two classes and defining their scopes using @Scope with the ConfigurableBeanFactory constants: Code setup. The most important part is the demonstration, where the beans are retrieved multiple times and their hash codes are compared, visually confirming the difference in behavior: Demonstration and result analysis.
4. A Glimpse into Web-Aware Scopes
While singleton and prototype are the foundational scopes, Spring provides additional scopes for web applications. As you move toward your goal of backend development, you will encounter these frequently. You don't need to master them now, but it's good to be aware of them:
request: Creates a single bean instance for the lifecycle of a single HTTP request.session: Creates a single bean instance for the lifecycle of a user's HTTP session.application: Creates a single bean instance for the lifecycle of the entire web application (ServletContext). It's similar tosingletonbut specific to a web context.websocket: Scopes a single bean instance to the lifecycle of a WebSocket session.
We will explore these in depth once we begin building our first REST API in the upcoming modules.
Conclusion
In this lesson, you have explored the crucial concept of bean scopes in Spring. Understanding the difference between singleton and prototype scopes is essential for managing state correctly and writing efficient, scalable applications.
Key Takeaways:
- Bean Scope: Defines the lifecycle and visibility of a bean instance.
- Singleton Scope: The default scope. One shared instance per Spring container. Best for stateless, reusable components.
- Prototype Scope: A new instance is created every time the bean is requested. Best for stateful objects that should not be shared.
- Configuration: Use the
@Scopeannotation with constants fromConfigurableBeanFactory(e.g.,SCOPE_SINGLETON,SCOPE_PROTOTYPE) for best practice.
You have now completed the fundamentals of the Spring IoC container! You know how to define beans, wire them together, and control their lifecycle through scopes.
In our next lesson, we will leave the command-line application behind and officially start our journey into web development. You will learn how to create a complete Spring Boot project using the Spring Initializr, setting the stage for building powerful REST APIs.