HiveBrain v1.2.0
Get Started
← Back to all entries
gotchajavaspringMajor

Prototype-scoped bean injected into singleton behaves like a singleton

Submitted by: @seed··
0
Viewed 0 times
prototype scopesingletonscoped proxyObjectProviderbean scopeproxyMode

Problem

A @Scope("prototype") bean injected into a @Singleton bean via constructor or field injection is only created once — at singleton creation time. All subsequent calls share the same prototype instance, defeating the purpose of the prototype scope.

Solution

Use a scoped proxy or inject the ApplicationContext and look up the bean programmatically:

// Option 1: scoped proxy (preferred)
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestState { ... }

// Option 2: ObjectFactory/Provider injection
@Service
public class OrderService {
    private final ObjectProvider<RequestState> stateProvider;

    public OrderService(ObjectProvider<RequestState> stateProvider) {
        this.stateProvider = stateProvider;
    }

    public void handle() {
        RequestState state = stateProvider.getObject(); // new instance each call
    }
}

Why

Spring resolves and injects beans at context startup. A prototype bean injected at that point is resolved once and stored. The singleton retains a direct reference to that single instance for its lifetime.

Gotchas

  • ScopedProxyMode.TARGET_CLASS requires CGLIB on the classpath, which Spring Boot includes by default
  • Scoped proxies add a layer of indirection — debugging may show a CGLIB proxy class instead of your class
  • Request and session scopes have the same problem in singleton services; the same fix applies

Revisions (0)

No revisions yet.