The bugfix #13814 "Scoped-proxy memory leak w/ @Resource injection" leads to bean instances being cached too eagerly in CommonAnnotationBeanPostProcessor. Besides the (desired) caching of AOP scoped-proxies to prevent the memory leak the current code also caches custom scoped bean instances that should not be cached. This happens for example if client code uses AutowireCapableBeanFactory#autowireBean(Object) to inject dependencies (annotation-based) into a manually created bean. In this case no AOP proxies are involved but the cached instances are still used. The underlying scope is never consulted and can thus never signalize that a new instance is to be created and injected because the context of the scope (e.g. request, session) is different from the first call which resulted in the cached instance.
I attached a Test-Case (JUnit 4 Test, requires JUnit and Spring to run). The test-case illustrates the breaking change:
Runs fine with Spring version 3.1.1 and older (tested with 3.0.5)
Fails with Spring version 3.1.2 and 3.2.M1
The defect was introduced in the bugfix for #13814 in version 3.2.M1 with commit f779c19
The defect was back-ported to version 3.1.2 with #14000
I understand this calling pattern is not very common but nevertheless the affected API is public and our framework relies on this to provide service beans to instances of "visual" classes (a visual models a single page in a web application). This basically renders custom scoped beans (also being used heavily) unusable for us in releases > 3.1.1, thus my classification as "major".
Samuel Bernet opened SPR-9627 and commented
The bugfix #13814 "Scoped-proxy memory leak w/
@Resource
injection" leads to bean instances being cached too eagerly inCommonAnnotationBeanPostProcessor
. Besides the (desired) caching of AOP scoped-proxies to prevent the memory leak the current code also caches custom scoped bean instances that should not be cached. This happens for example if client code usesAutowireCapableBeanFactory#autowireBean(Object)
to inject dependencies (annotation-based) into a manually created bean. In this case no AOP proxies are involved but the cached instances are still used. The underlying scope is never consulted and can thus never signalize that a new instance is to be created and injected because the context of the scope (e.g. request, session) is different from the first call which resulted in the cached instance.I attached a Test-Case (JUnit 4 Test, requires JUnit and Spring to run). The test-case illustrates the breaking change:
I understand this calling pattern is not very common but nevertheless the affected API is public and our framework relies on this to provide service beans to instances of "visual" classes (a visual models a single page in a web application). This basically renders custom scoped beans (also being used heavily) unusable for us in releases > 3.1.1, thus my classification as "major".
Best regards
Samuel Bernet
MSc ETH Software Engineering
samuel.bernet@raiffeisen.ch
Affects: 3.1.2, 3.2 M1
Attachments:
Issue Links:
@Resource
injection regression with scope prototype ("is duplicated by")@Resource
injection@Resource
appears to be broken@Resource
injection"@Resource
injection of singleton in prototype using AnnotationConfigApplicationContext is not thread-safeReferenced from: commits 04af54a, 26ee0c4, 68c5f20, 1971870
1 votes, 5 watchers
The text was updated successfully, but these errors were encountered: