DEV Community

Hunor Vadasz-Perhat
Hunor Vadasz-Perhat

Posted on

πŸ“Œ spring-note-004: Understanding Spring Bean Scopes

(Reference: Spring Docs - Bean Scopes)


πŸ”Ή What is a Bean Scope?

πŸ’‘ Bean Scope determines how long a bean lives and how many instances exist in the application.

πŸ’‘ Spring provides different scopes to manage beans depending on the use case.


πŸ“Œ Types of Bean Scopes in Spring

πŸ”₯ Spring defines several bean scopes, divided into two categories:

  • Singleton & Prototype β†’ Standard scopes (used in ANY Spring app).
  • Request, Session, Application, WebSocket β†’ Web-specific scopes.

1️⃣ Singleton Scope (Default)

βœ… Only ONE instance exists for the entire application context.

βœ… Same instance is returned every time the bean is requested.

βœ… Best for stateless, reusable components (e.g., Service classes).

πŸ“Œ Example:

import org.springframework.stereotype.Component;

@Component
public class PirateCaptain {
    public PirateCaptain() {
        System.out.println("πŸ΄β€β˜ οΈ Singleton Pirate Captain Created!");
    }
}
Enter fullscreen mode Exit fullscreen mode

πŸ”₯ Spring ensures only ONE PirateCaptain instance exists!


2️⃣ Prototype Scope

βœ… A NEW instance is created every time the bean is requested.

βœ… Used for stateful objects that require separate instances.

βœ… Good for expensive objects that should NOT be shared.

πŸ“Œ Example:

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

@Component
@Scope("prototype")
public class TreasureMap {
    public TreasureMap() {
        System.out.println("πŸ—ΊοΈ New Treasure Map Created!");
    }
}
Enter fullscreen mode Exit fullscreen mode

πŸ”₯ Each time you getBean(TreasureMap.class), a new instance is returned!


3️⃣ Request Scope (For Web Applications)

βœ… One instance per HTTP request (lives as long as the request).

βœ… Useful for objects needed only during request processing.

πŸ“Œ Example:

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

@Component
@Scope("request")
public class ShipLog {
    public ShipLog() {
        System.out.println("πŸ“œ New Ship Log Created for Request!");
    }
}
Enter fullscreen mode Exit fullscreen mode

πŸ”₯ Every new HTTP request gets a new ShipLog instance!


4️⃣ Session Scope (For Web Applications)

βœ… One instance per user session (persists across multiple requests).

βœ… Useful for session-based user data.

πŸ“Œ Example:

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

@Component
@Scope("session")
public class PirateSession {
    public PirateSession() {
        System.out.println("πŸ΄β€β˜ οΈ New Pirate Session Created!");
    }
}
Enter fullscreen mode Exit fullscreen mode

πŸ”₯ Every user gets their own PirateSession bean across multiple requests.


5️⃣ Application Scope (For Web Applications)

βœ… One instance for the ENTIRE application (shared across all requests & users).

βœ… Useful for storing global application data.

πŸ“Œ Example:

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

@Component
@Scope("application")
public class GlobalPirateRules {
    public GlobalPirateRules() {
        System.out.println("πŸ“œ Global Pirate Rules Initialized!");
    }
}
Enter fullscreen mode Exit fullscreen mode

πŸ”₯ The same instance is shared across all users and requests.


πŸ“Œ Hands-On Project: Exploring Bean Scopes

πŸ’‘ Let’s create a simple Spring Boot app to experiment with different bean scopes!


Step 1: Create a Spring Boot Project

1️⃣ Go to Spring Initializr

2️⃣ Select:

  • Spring Boot Version: Latest stable
  • Dependencies: Spring Web
  • Packaging: Jar 3️⃣ Click Generate and extract the zip file.

Step 2: Create Beans with Different Scopes

πŸ“Œ Create a Singleton Bean:

import org.springframework.stereotype.Component;

@Component
public class SingletonPirate {
    public SingletonPirate() {
        System.out.println("πŸ΄β€β˜ οΈ Singleton Pirate Created!");
    }
}
Enter fullscreen mode Exit fullscreen mode

πŸ“Œ Create a Prototype Bean:

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

@Component
@Scope("prototype")
public class PrototypeTreasure {
    public PrototypeTreasure() {
        System.out.println("πŸ’Ž New Prototype Treasure Created!");
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Inject and Test Scopes in a REST Controller

πŸ“Œ Create a ScopeController to observe bean behavior:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/scopes")
public class ScopeController {

    private final SingletonPirate singletonPirate;
    private final PrototypeTreasure prototypeTreasure;

    public ScopeController(SingletonPirate singletonPirate, PrototypeTreasure prototypeTreasure) {
        this.singletonPirate = singletonPirate;
        this.prototypeTreasure = prototypeTreasure;
    }

    @GetMapping("/singleton")
    public String getSingleton() {
        return "πŸ΄β€β˜ οΈ Singleton Pirate Hash: " + singletonPirate.hashCode();
    }

    @GetMapping("/prototype")
    public String getPrototype() {
        return "πŸ’Ž Prototype Treasure Hash: " + prototypeTreasure.hashCode();
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Run the Application & Test

πŸ’‘ Run the app using:

mvn spring-boot:run
Enter fullscreen mode Exit fullscreen mode

or

./mvnw spring-boot:run
Enter fullscreen mode Exit fullscreen mode

πŸ“Œ Open browser & test the endpoints:
1️⃣ Call Singleton Endpoint:

  • http://localhost:8080/scopes/singleton
  • Response:

     πŸ΄β€β˜ οΈ Singleton Pirate Hash: 12345678
    
  • Same value every time!

2️⃣ Call Prototype Endpoint Multiple Times:

  • http://localhost:8080/scopes/prototype
  • Response:

     πŸ’Ž Prototype Treasure Hash: 87654321
    
  • Different value each time!

πŸ”₯ Boom! You just witnessed Spring Bean Scopes in action!


πŸ“Œ Summary of Step 4

βœ… Singleton (Default): One instance per application.

βœ… Prototype: A new instance every time.

βœ… Request: One instance per HTTP request (Web apps only).

βœ… Session: One instance per user session (Web apps only).

βœ… Application: One instance for the entire app (Web apps only).


πŸ“Œ Topics Covered in This Section
πŸ“œ Spring Bean Scopes (βœ”οΈ Covered)

  • Singleton (Default scope, one instance per container).
  • Prototype (New instance every time).
  • Request Scope (New instance per HTTP request).
  • Session Scope (New instance per user session).
  • Application Scope (Shared instance for the entire application).

πŸ› οΈ Spring Boot & Scopes (βœ”οΈ Covered)

  • Using @scope annotation.
  • How singleton vs. prototype works in dependency injection.
  • Scope behavior in REST APIs.

πŸ”₯ Key Takeaways You Need to Remember:
βœ… Singleton is the default scope.
βœ… Prototype creates a new bean instance every time.
βœ… Web scopes (Request, Session, Application) require Spring Web.
βœ… Use @scope("prototype") carefully when injecting into Singleton beans (can cause issues).

Top comments (0)