I thought I understood how Spring deals with prototype-scope beans: when injected into another bean as a dependency, or explicitly retrieved from a BeanFactory
via 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.