Skip to main content

Bean Scopes in Spring

Bean Scopes in Spring Framework: Complete Deep Dive

In the Spring Framework, Bean Scope defines how many physical instances of a bean Spring should create, and exactly how long those objects should survive inside the Inversion of Control (IOC) Container.

This is a massively important architecture topic because getting the scope wrong directly impacts:

  • Memory Usage (Creating too many objects crashes the heap)
  • Performance (Constantly creating heavy objects slows the CPU)
  • Concurrency & Thread Safety (Shared state causes silent data corruption)

1. What is Bean Scope?

Consider a simple service class:

@Service public class EmployeeService { }

Question: How many EmployeeService objects will Spring physically create in memory?

Answer: It depends entirely on the declared Scope.

[ Spring IOC Container ] | ----------------------------------- | | | | | Singleton Prototype Request Session Application

2. Singleton Scope (The Default)

Standard Definition

Singleton scope instructs Spring to create exactly one instance of a bean per IOC Container. This single instance is cached and shared across the entire application.

Because it is the default scope, both of these declarations do exactly the same thing:

@Service @Scope("singleton") public class EmployeeService { } // Equivalent to: @Service public class EmployeeService { }

Internal Backend Cache: `singletonObjects`

When the application starts, Spring scans the classes, instantiates the singleton bean exactly once, and stores it in an internal memory map called singletonObjects (which lives inside the DefaultSingletonBeanRegistry class).

// Conceptual backend representation Map<String, Object> singletonObjects = new ConcurrentHashMap<>(); singletonObjects.put("employeeService", newEmployeeServiceObject);

Whenever a Controller requests the EmployeeService, Spring doesn't create a new object. It simply fetches the existing object from the singletonObjects cache and returns its memory reference.

The Thread Safety Problem

Because there is only one object shared across the entire application, multiple HTTP request threads will execute methods on that exact same object simultaneously.

If your Singleton bean contains state (instance variables), you will suffer fatal Race Conditions. Therefore, Singleton beans should always be entirely Stateless.


3. Prototype Scope

Standard Definition

A new, completely fresh bean instance is created every single time the bean is requested from the container.

@Component @Scope("prototype") public class Employee { }

When you call context.getBean(Employee.class) three times, Spring will execute the new Employee() constructor three separate times, returning Object A, Object B, and Object C. The singletonObjects cache is completely bypassed.

Important Interview Point: Destruction Management

For Prototype beans, Spring manages the creation and initialization (including @PostConstruct). However, Spring does NOT manage destruction.

Once Spring hands you a prototype bean, it forgets about it. The @PreDestroy method will never be executed for a prototype bean. The JVM Garbage Collector handles the cleanup.


4. Web-Aware Scopes (Request, Session, Application)

These scopes are only available in Web Applications (Spring MVC / Spring WebFlux).

Request Scope

Creates one object per HTTP Request. Once the request is fully processed and the response is sent, the bean is destroyed.

@Component @RequestScope public class UserContext { }

Real Example: Storing a parsed JWT token, Request ID, or temporarily authenticated user info for the lifecycle of a single API call.

Session Scope

Creates one object per HTTP Session. The bean survives across multiple requests from the exact same user, but is isolated from other users.

@Component @SessionScope public class ShoppingCart { }

Real Example: Storing products in a user's shopping cart. User A gets Cart A, User B gets Cart B.

Application Scope

Creates one bean per ServletContext. It is essentially identical to a Singleton, but it operates at the Servlet container level rather than the Spring ApplicationContext level.


5. Singleton vs Prototype (The Ultimate Comparison)

Feature Singleton Prototype
Default Scope? Yes No
Objects Created Exactly One Many (One per request)
Cache Used? Yes (singletonObjects) No
Memory Usage Very Low High
Performance Extremely Fast Slower (repeated object creation)
Thread Safety Dangerous (Must be stateless) Safe (No shared state)
Destroy Managed? Yes (by Spring) No (by Garbage Collector)

6. The Most Asked Interview Question

Q: What happens when you inject a Prototype Bean into a Singleton Bean?

Many developers think: "Because the injected bean is a Prototype, every time I call a method on the Service, it will use a brand new Prototype instance."

This is entirely WRONG.

Consider this setup:

@Component @Scope("prototype") public class Employee { } @Service // Singleton by default public class EmployeeService { @Autowired Employee employee; }

The Reality: The EmployeeService is a Singleton. It is created only once at application startup. Therefore, its dependencies are injected only once.

Spring creates one single Employee prototype, injects it into the EmployeeService, and stops. From that point on, the Singleton Service will hold onto that exact same Prototype instance forever.

The Solution: ObjectProvider

If you genuinely need a fresh Prototype instance every time a method is called inside a Singleton, you must inject an ObjectProvider:

@Service public class EmployeeService { @Autowired private ObjectProvider<Employee> employeeProvider; public void process() { // This fetches a brand new instance every single time! Employee freshEmployee = employeeProvider.getObject(); } }

7. Complete Backend Working Flow Diagram

If an interviewer asks you to map the internal architectural flow of Bean Scopes, use this diagram:

SpringApplication.run() | ApplicationContext Created | Component Scan → BeanDefinition Created | Read Scope Metadata from BeanDefinition | +---- Scope = SINGLETON | | | V | Create Once & Store In singletonObjects Cache | +---- Scope = PROTOTYPE | | | V | Create New Instance Per IOC Request (No Cache) | +---- Scope = REQUEST | | | V | Create Per Incoming HTTP Request | +---- Scope = SESSION | V Create Per User HTTP Session

Comments

Popular posts from this blog

How I Got Selected in MNC

Virtusa Sometimes success does not come from having the best coding skills or the perfect roadmap. Sometimes it comes from simply refusing to quit. This is the honest story of how I transitioned from a confused, rejected fresher to getting selected as an Associate Engineer at Virtusa. The Beginning: Confused About My Future After completing my graduation, I stared blankly at my career options. Like many freshers, I lacked a clear direction. Should I join a Java course? Should I prepare on my own? Should I just wait for campus placement opportunities? One day, I called my friend Chetan. He suggested I join Naresh i Technologies and start learning Java seriously. Still unsure of my path, I told him I needed time to think about it. A couple of days later, my phone buzzed with a WhatsApp message offering a job opportunity. They asked me to come for the next round of the recruitment process. Excitement completely took over. I packed my bags, traveled to th...

Spring Boot Introduction

Spring Boot Introduction: Architecture, Dependencies, and Embedded Servers Modern enterprise applications demand rapid development, frictionless deployment, and absolute minimal configuration. Before Spring Boot arrived, developers utilizing the Spring Framework wasted immense amounts of time configuring XML files, managing clashing dependencies, setting up clunky application servers, and stitching various Spring modules together manually. To eliminate these bottlenecks, Pivotal introduced Spring Boot . Built entirely on top of the traditional Spring Framework, Spring Boot is an "opinionated" framework. It aggressively simplifies application development by injecting auto-configuration, packaging starter dependencies, and embedding web servers directly into your application. This allows backend developers to focus entirely on building business logic rather than wrestling with infrastructure setup. What is Spring Boot? Spring Boot is a powerful extens...

Strings in C

C Programming: Working with Strings Unlike modern programming languages like Python or Java, C does not possess a dedicated "String" data type. Instead, C treats a string as a simple 1D array of characters. Real-life example: Think of a freight train. The train does not exist as one solid object; it consists of individual boxcars linked together. Similarly, a C string links individual characters side-by-side in memory. To let the computer know the train has ended, C attaches a special "caboose" called the Null Terminator ( \0 ). 1. Essential String Functions Handling strings manually requires complex loops. To save time, C provides a built-in library called <string.h> that contains powerful functions to manipulate text. strlen(): You use this to find the exact length of a string. The compiler counts the characters until it hits the \0 terminator. It does not count the terminator itself. strcpy(): You ...