0
0
Spring Bootframework~15 mins

@Scope for bean scope in Spring Boot - Deep Dive

Choose your learning style9 modes available
Overview - @Scope for bean scope
What is it?
@Scope is an annotation in Spring Boot that controls the lifecycle and visibility of a bean. It tells Spring how long a bean should live and how many instances should be created. Common scopes include singleton (one instance for the whole app) and prototype (a new instance every time). This helps manage resources and behavior in your application.
Why it matters
Without @Scope, all beans would behave the same way, usually as singletons. This can cause problems when you need fresh data or separate instances for different users or requests. @Scope solves this by letting you control bean creation and lifespan, making your app more efficient and easier to maintain. Imagine if every tool in a workshop was shared by everyone all the time — it would cause delays and confusion.
Where it fits
Before learning @Scope, you should understand what beans are and how Spring manages them with dependency injection. After mastering @Scope, you can explore advanced Spring features like custom scopes, request/session scopes in web apps, and lifecycle callbacks.
Mental Model
Core Idea
@Scope defines how many copies of a bean exist and how long each copy lives in the Spring container.
Think of it like...
Think of @Scope like renting cars: singleton is like having one car shared by everyone all the time, prototype is like renting a new car every time you need one, and request/session scopes are like renting a car only for a specific trip or user session.
┌─────────────┐       ┌─────────────┐
│ Spring App │       │ Spring App │
│ Container  │       │ Container  │
│             │       │             │
│ [Singleton]│──────▶│ One shared  │
│ Bean       │       │ instance   │
│             │       │             │
│ [Prototype]│──────▶│ New instance│
│ Bean       │       │ every time │
└─────────────┘       └─────────────┘
Build-Up - 7 Steps
1
FoundationWhat is a Spring Bean
🤔
Concept: Introduce the idea of a Spring bean as a managed object in the Spring container.
In Spring Boot, a bean is an object that Spring creates and manages for you. You define beans by annotating classes or methods, and Spring handles their lifecycle and dependencies automatically. Beans are the building blocks of your application logic.
Result
You understand that beans are objects controlled by Spring, not created manually.
Understanding beans is essential because @Scope controls how these objects are created and reused.
2
FoundationDefault Bean Scope: Singleton
🤔
Concept: Explain that by default, Spring beans are singletons, meaning one instance per container.
When you create a bean without specifying @Scope, Spring makes only one instance of it. Every time you ask for that bean, you get the same object. This saves memory and ensures consistent state across the app.
Result
You know that singleton beans are shared and reused everywhere in the app.
Knowing the default scope helps you realize when you need to change it for different behavior.
3
IntermediatePrototype Scope: New Instance Each Time
🤔Before reading on: do you think prototype beans share the same instance or create a new one each time? Commit to your answer.
Concept: Introduce prototype scope where Spring creates a new bean instance every time it is requested.
By adding @Scope("prototype") to a bean, Spring will create a fresh object each time you ask for it. This is useful when you want independent copies that don't share state.
Result
You get a new bean instance on every request instead of sharing one.
Understanding prototype scope helps you manage stateful beans that must not be shared.
4
IntermediateRequest and Session Scopes in Web Apps
🤔Before reading on: do you think request scope beans live shorter than session scope beans? Commit to your answer.
Concept: Explain special scopes for web applications: request scope lives for one HTTP request, session scope lives for a user session.
In web apps, you can use @Scope("request") to create a bean that lasts only for one HTTP request. @Scope("session") creates a bean that lasts for the whole user session. These scopes help manage user-specific data safely.
Result
Beans are created and destroyed based on web request or user session lifetimes.
Knowing these scopes is key for building web apps that handle user data correctly and efficiently.
5
IntermediateUsing @Scope with Proxy Mode
🤔Before reading on: do you think prototype beans injected into singleton beans behave as new instances each time or just once? Commit to your answer.
Concept: Introduce proxy mode to allow prototype beans to be injected into singleton beans and still create new instances on each use.
When a singleton bean depends on a prototype bean, Spring by default injects only one prototype instance. To get a new prototype instance each time, you use @Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS). This creates a proxy that fetches a fresh instance on demand.
Result
Prototype beans behave correctly even when injected into singletons, avoiding stale shared state.
Understanding proxy mode prevents common bugs with mixed bean scopes in real apps.
6
AdvancedCustom Scopes and Lifecycle Callbacks
🤔Before reading on: do you think you can create your own bean scopes beyond the built-in ones? Commit to your answer.
Concept: Explain that Spring allows defining custom scopes and lifecycle callbacks for beans.
Beyond built-in scopes, you can create custom scopes by implementing Scope interface. This is useful for special cases like conversation scope or application-specific lifetimes. Also, beans can have lifecycle callbacks like @PostConstruct and @PreDestroy to run code on creation and destruction.
Result
You can tailor bean lifecycles to complex application needs.
Knowing custom scopes and callbacks unlocks advanced control over bean behavior in production.
7
ExpertHow Spring Manages Scoped Proxies Internally
🤔Before reading on: do you think Spring creates a new class or uses dynamic proxies to implement scoped proxies? Commit to your answer.
Concept: Reveal the internal mechanism of scoped proxies using dynamic proxies or CGLIB to delegate calls to the correct scoped instance.
Spring creates a proxy object that looks like the bean but delegates method calls to the actual scoped instance at runtime. For interfaces, it uses JDK dynamic proxies; for classes, it uses CGLIB bytecode generation. This allows seamless injection and correct scope behavior without changing client code.
Result
Scoped proxies enable flexible scope management without manual coding.
Understanding this mechanism explains why proxies sometimes cause class cast exceptions or require interfaces.
Under the Hood
Spring maintains a registry of bean definitions with their scopes. When a bean is requested, Spring checks its scope: for singleton, it returns the same instance; for prototype, it creates a new one each time. For scoped proxies, Spring generates a proxy object that intercepts calls and delegates them to the correct scoped instance dynamically at runtime.
Why designed this way?
This design balances performance and flexibility. Singleton scope saves memory and startup time. Prototype and other scopes provide fresh instances when needed. Proxies allow mixing scopes without changing client code, preserving dependency injection benefits. Alternatives like manual bean creation would be error-prone and less maintainable.
┌───────────────┐
│ Bean Request  │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Check Scope   │
├───────────────┤
│ Singleton?    │───Yes──▶ Return same instance
│ Prototype?    │───Yes──▶ Create new instance
│ Scoped Proxy? │───Yes──▶ Return proxy object
└──────┬────────┘          │
       │                   ▼
       │            ┌───────────────┐
       │            │ Proxy intercept│
       │            │ calls and     │
       │            │ delegate to   │
       │            │ correct bean  │
       │            └───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does @Scope("prototype") mean Spring will always create a new instance even when injected into a singleton? Commit yes or no.
Common Belief:Prototype scope always creates a new instance every time, no matter what.
Tap to reveal reality
Reality:When a prototype bean is injected into a singleton bean, Spring creates only one prototype instance at injection time unless proxy mode is used.
Why it matters:Without proxy mode, prototype beans behave like singletons inside singletons, causing unexpected shared state and bugs.
Quick: Is singleton scope the same as Java's singleton design pattern? Commit yes or no.
Common Belief:Spring's singleton scope means the same as the classic singleton design pattern in Java.
Tap to reveal reality
Reality:Spring singleton scope means one instance per Spring container, not globally per JVM or classloader as in the singleton pattern.
Why it matters:Confusing these can lead to wrong assumptions about bean lifecycle and cause issues in multi-container or multi-threaded environments.
Quick: Do request and session scopes work outside web applications? Commit yes or no.
Common Belief:Request and session scopes can be used in any Spring application.
Tap to reveal reality
Reality:Request and session scopes only work in web-aware Spring contexts where HTTP requests and sessions exist.
Why it matters:Using these scopes in non-web apps causes errors or unexpected behavior.
Quick: Does adding @Scope("prototype") automatically make a bean thread-safe? Commit yes or no.
Common Belief:Prototype beans are always thread-safe because each request gets a new instance.
Tap to reveal reality
Reality:Prototype scope does not guarantee thread safety; if multiple threads share the same instance or state, synchronization is still needed.
Why it matters:Assuming thread safety can cause subtle concurrency bugs in multi-threaded apps.
Expert Zone
1
Scoped proxies can cause class cast exceptions if the proxy type does not match the expected bean type, especially when using class-based proxies without interfaces.
2
Custom scopes require careful lifecycle management to avoid memory leaks, especially when beans hold resources that need explicit cleanup.
3
Mixing scopes in complex dependency graphs can lead to subtle bugs if lifecycle and proxying are not fully understood.
When NOT to use
Avoid using prototype scope for beans that manage shared resources or require global state consistency; use singleton or other scopes instead. For web apps, if you need per-request or per-session data, use request or session scopes rather than prototype. When you need fine-grained control over bean lifecycle, consider using lifecycle callbacks or custom scopes.
Production Patterns
In real-world Spring Boot apps, singleton scope is used for stateless services and repositories. Prototype scope is common for stateful components like form backing beans. Request and session scopes are used in web controllers and user session data. Scoped proxies are often used to inject request-scoped beans into singleton services without breaking dependency injection.
Connections
Dependency Injection
Builds-on
Understanding @Scope deepens your grasp of dependency injection by showing how object lifecycles and sharing are controlled, not just how dependencies are wired.
Object Pooling (Software Engineering)
Similar pattern
Both @Scope and object pooling manage object lifecycles to optimize resource use, but @Scope integrates lifecycle control into the container automatically.
Session Management (Web Development)
Builds-on
Request and session scopes in Spring relate directly to how web sessions and requests are managed, linking backend bean lifecycles to user interactions.
Common Pitfalls
#1Injecting a prototype bean into a singleton without proxy mode causes shared instance usage.
Wrong approach:@Component @Scope("prototype") public class MyPrototypeBean {} @Component public class MySingletonBean { private final MyPrototypeBean prototypeBean; public MySingletonBean(MyPrototypeBean prototypeBean) { this.prototypeBean = prototypeBean; } public void doSomething() { prototypeBean.action(); } }
Correct approach:@Component @Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS) public class MyPrototypeBean {} @Component public class MySingletonBean { private final MyPrototypeBean prototypeBean; public MySingletonBean(MyPrototypeBean prototypeBean) { this.prototypeBean = prototypeBean; } public void doSomething() { prototypeBean.action(); } }
Root cause:Misunderstanding that prototype scope alone creates new instances on every use, ignoring injection time behavior.
#2Using request scope in a non-web Spring application causes errors.
Wrong approach:@Component @Scope("request") public class RequestBean {}
Correct approach:Use singleton or prototype scope in non-web apps, or configure a web-aware context before using request scope.
Root cause:Assuming all scopes work everywhere without considering application context type.
#3Assuming singleton scope means global JVM singleton.
Wrong approach:@Component public class GlobalSingleton {} // expecting one instance across JVM
Correct approach:Understand singleton is per Spring container; for JVM-wide singleton, use static or enum patterns.
Root cause:Confusing Spring container scope with Java language design patterns.
Key Takeaways
@Scope controls how many instances of a Spring bean exist and how long they live.
Singleton is the default scope, meaning one shared instance per Spring container.
Prototype scope creates a new instance every time the bean is requested, but special care is needed when injecting into singletons.
Web applications use request and session scopes to tie bean lifecycles to HTTP requests and user sessions.
Scoped proxies enable mixing bean scopes safely by delegating calls to the correct instance dynamically.