Question 11 · Section 5

What Scopes Exist in Spring?

4. Scoped Proxy - for injecting narrow scopes into wider ones 5. ObjectProvider - alternative to Scoped Proxy 6. RefreshScope - for dynamic configuration

Language versions: English Russian Ukrainian

Junior Level

Scope defines how many instances of a bean Spring creates.

Scope How many instances
Singleton One for the entire application (default)
Prototype New on each request
Request One per HTTP request
Session One per HTTP session
@Service              // Singleton
public class UserService { }

@Scope("prototype")
@Service
public class Report { }  // New each time

Middle Level

Standard Scopes

Singleton:

// One instance per ApplicationContext
// All threads use the same object
// -> Must be Stateless!

Prototype:

// New on each getBean()
// Spring does NOT call @PreDestroy!
// -> You clean resources yourself

Web Scopes

@Scope("request")     // One per HTTP request
@Scope("session")     // One per user session
@Scope("application") // One per ServletContext

Custom Scopes

// Your own scope!
context.getBeanFactory().registerScope("thread", new ThreadScope());
// ThreadScope - custom implementation of org.springframework.beans.factory.config.Scope interface.
// Stores beans in ThreadLocal. Not built into standard Spring - this is an example.

// Spring Cloud: Refresh Scope
// -> Bean is recreated when configuration is updated

Problem: Narrow Scope in Singleton

// Request bean created once at Singleton startup
@Service
public class SingletonService {
    @Autowired RequestBean requestBean;  // Stuck with the first one!
}

// Scoped Proxy
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
@Bean public RequestBean requestBean() { }

// ObjectProvider
@Autowired ObjectProvider<RequestBean> provider;
RequestBean bean = provider.getObject();  // Actual!

Senior Level

ScopedProxyMode

TARGET_CLASS (CGLIB):
  -> Creates proxy subclass
  -> Proxy -> RequestContextHolder -> actual bean

INTERFACES (JDK):
  -> Proxies only interfaces

NO:
  -> No proxy -> problem with Singleton

Under the Hood: Where They Are Stored

Singleton -> DefaultSingletonBeanRegistry (ConcurrentHashMap)
Request -> stored in HttpServletRequest attributes, accessed via RequestContextHolder (ThreadLocal)
Session -> SessionAttributes
Prototype -> Not stored, created each time

Refresh Scope (Spring Cloud)

@RefreshScope
@ConfigurationProperties("my.config")
public class MyConfig { }

// On update via Spring Cloud Bus:
// -> Proxy is invalidated
// -> On next request, recreated with new data

Production Experience

Real scenario: Session scope in microservice

Session scope -> ThreadLocal -> works on one node
-> Load Balancer -> request to another node -> Session lost!

Solution: Spring Session + Redis
-> Session stored in Redis -> available on all nodes

Best Practices

  1. Singleton - for services and repositories
  2. Prototype - for heavy stateful objects
  3. Web scopes - for user data
  4. Scoped Proxy - for injecting narrow scopes into wider ones
  5. ObjectProvider - alternative to Scoped Proxy
  6. RefreshScope - for dynamic configuration

Summary for Senior

  • Singleton = one per ApplicationContext
  • Prototype = new each time, @PreDestroy does NOT work
  • Request/Session = web scope via ThreadLocal
  • Scoped Proxy = proxy -> RequestContextHolder
  • RefreshScope = recreation on config update
  • Custom Scope = your own lifecycle

Interview Cheat Sheet

Must know:

  • 4 standard scopes: Singleton (default), Prototype, Request, Session
  • Singleton = one instance per ApplicationContext, Prototype = new on each request
  • Web scopes (Request/Session) stored via ThreadLocal
  • ScopedProxyMode (TARGET_CLASS/CGLIB, INTERFACES/JDK, NO) solves the problem of injecting narrow scopes into wider ones
  • @PreDestroy is NOT called for Prototype - clean resources manually
  • ObjectProvider - alternative to Scoped Proxy for Prototype/Request in Singleton
  • RefreshScope (Spring Cloud) - bean recreation on configuration update

Common follow-up questions:

  • How to inject Request scope into Singleton? -> Scoped Proxy (proxyMode = TARGET_CLASS) or ObjectProvider
  • What happens if a Prototype bean holds resources? -> Leak, Spring will not call @PreDestroy, need to clean manually via try-finally
  • Where does Spring store Singleton beans? -> DefaultSingletonBeanRegistry (ConcurrentHashMap)
  • What does RefreshScope do? -> Invalidates proxy, recreates bean with new data on next request

Red flags (DO NOT say):

  • “Prototype calls @PreDestroy” - does not call
  • “Request scope is stored in Spring cache” - stored in HttpServletRequest attributes
  • “Singleton is created on each access” - created once
  • “Custom Scope is built into Spring” - you need to write your own Scope interface implementation

Related topics:

  • [[12. Difference between singleton and prototype scope]]
  • [[13. What is a proxy in Spring]]
  • [[14. When does Spring create a proxy]]
  • [[16. What is aspect advice pointcut join point]]