Skip to content

Support DisposableBean on prototype and @Configurable beans using weak references [SPR-9391] #14027

Closed as not planned
@spring-projects-issues

Description

@spring-projects-issues

Archie Cobbs opened SPR-9391 and commented

Spring has some very counter-intuitive behavior when handling prototype scoped and @Configurable beans, or more generally, beans whose lifecycles are "smaller" than the lifecycle of the overall application context (e.g., that of singleton beans).

The issue is that initialization activity occurs for these beans (e.g., InitializingBean) but destruction activity does not (e.g., DisposableBean). For just one example, #11326 complains about this.

Related to this is the non-intuitive behavior that ApplicationListener doesn't work at all for prototype and @Configurable beans, presumably because there's no way for the application context to know when to unregister the listener (e.g., see the code quoted in #14023).

This contributes to much confusion about Spring. But even worse, the typical result for unaware programmers is memory leaks. This is due to destruction activity that never occurs, such as listeners that don't get unregistered, etc. In a servlet container environment, this can then cause class loader leaks on web application restart, etc.

All of these problems can be solved easily: have the application context maintain weak references to these beans, along with a corresponding reference queue, and invoke all of the destruction callbacks whenever any bean appears on the reference queue. In addition, when the application context itself is shutdown, since there can still be "live" prototype and @Configurable beans, we need to find and destruct them; but these beans will exist as uncleared weak references, which can then be iteratively destructed (presumably we are discarding the weak references after destructing the corresponding bean, so at any given time the weak references we maintain represent only the "live" beans).

To avoid having to create a new thread to poll the reference queue, the application context can poll the reference queue every time a new prototype or @Configurable bean is instantiated, etc. This ensures that there can be no memory leak caused by the maintenance of the references themselves. Regarding the behavior of destructor timing, in the worst case, beans will be always be destructed on application context shutdown, but typically much sooner. Better late than never!

FYI, this idea was originally mentioned in #9922; I'm just elaborating on it.


Affects: 3.1.1

Issue Links:

2 votes, 4 watchers

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)status: bulk-closedAn outdated, unresolved issue that's closed in bulk as part of a cleaning processtype: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions