I thought I understood how Spring deals with prototype-scope beans: when injected into another bean as a dependency, or explicitly retrieved from a
getBean, a new instance is always created. Thus, when injected as a dependency the prototype bean effectively shares the same lifecycle as the bean it’s injected into (except that destroy listeners aren’t called).
That’s correct if scoped proxies aren’t being used, but is not correct if they are. If scoped proxies are enabled, a scoped proxy is instead injected, and a new instance of the prototype bean is created every time the proxy is accessed! I don’t see that behavior discussed in the Spring docs. It seems like it fulfils the goals of method injection in an easier fashion.
While that behavior might be useful at times, it seems a rather subtle way to enable it. If explicitly declaring the
proxyMode when declaring bean scope, it’s obvious enough, but if declaring the type of scoped proxies you want across the system using
scopedProxy on a
@ComponentScan annotation (or
scoped-proxy on a
<context:component-scan> tag), this drastically changes the behavior of all prototype-scope beans it picks up.
Perhaps the best practice is to always explicitly declare a
proxyMode attribute on all
@Scope("prototype") annotations, to make the decision explicit.