Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Prototype Beans and Benefits of Spring

I've been gradually getting to grips with Spring for a while now and think I have a reasonable idea of the concepts however I came across information in another of my threads which turned things upside down for me...

"...although initialization lifecycle callback methods are called on all objects regardless of scope, in the case of prototypes, configured destruction lifecycle callbacks are not called. The client code must clean up prototype-scoped objects and release expensive resources that the prototype bean(s) are holding. To get the Spring container to release resources held by prototype-scoped beans, try using a custom bean post-processor, which holds a reference to beans that need to be cleaned up."

This got me thinking that I have real use cases where I'd like to use prototype beans where, for example, I need a "new" bean instance per request. However from what I understand of this snippet (from the Spring 3 docs) Spring holds on to a reference to beans that need to be cleaned up (the reference itself meaning that the bean will not be cleared automatically by the garbage collector). Furthermore I take it from this that the resources held by the prototype bean have to be manually cleaned up.

Can somebody let me know if this is correct? If so is there a typical pattern used to deal with this? I'd appreciate an answer which could describe the architectural reason why Spring implements prototype beans in this manner.

like image 803
raven-king Avatar asked Jun 08 '12 21:06

raven-king


3 Answers

Spring holds on to a reference to beans that need to be cleaned up (the reference itself meaning that the bean will not be cleared automatically by the garbage collector).

Yes, but the container does not hold references to prototype-scoped beans. This is the reason why destruction callbacks are not called: Spring creates bean instance, wires it and calls construction callbacks. It gives an instance and forgets about that bean.

You can safely create prototype-scoped beans per request. Spring will give you an instance and the moment you don't have any references to that bean (Spring does not keep one!), it will be garbage collected. But since Spring doesn't know anything about your bean after creating it - it can't call any destruction callback. In fact this this boils down to a question: why Java doesn't have destructors.

So how do you clean up prototype-scoped beans? Well, just like you clean up any other resources in Java - explicitly. Provide close(), destroy(), stop() or whatever name you like (consider implementing Closeable. Note that such methods aren't typically needed. Garbage collector will release the whole object graph while persistent resource like database connections will be closed when the whole DataSource is closed.

like image 121
Tomasz Nurkiewicz Avatar answered Nov 08 '22 17:11

Tomasz Nurkiewicz


You misread the documentation. It explicitely says:

To get the Spring container to release resources held by prototype-scoped beans, try using a custom bean post-processor, which holds a reference to beans that need to be cleaned up.

So Spring does not hold any reference to the prototype beans it creates. It's up to you to create a bean post-processor that would hold references to these beans if needed.

Moreover, it's pretty rare for prototype beans to hold resources that must be cleaned up. For example, a connection pool (which needs to be destroyed properly at shutdown) is typically a singleton bean. It wouldn't make much sense to make it a prototype. Since prototype beans are often used for a small amount of time, the client creating it can explicitely release its resources when it doesn't use it anymore. Just like when you create a new stream or connection, and close it in a finally block.

like image 27
JB Nizet Avatar answered Nov 08 '22 19:11

JB Nizet


Spring has no knowledge regarding all instances created using prototype scope. It will simply instantiate and configure prototype scoped beans and hand it over to the client as commented on the documentation.

Spring does not manage the complete lifecycle of a prototype bean: the container instantiates, configures, decorates and otherwise assembles a prototype object, hands it to the client and then has no further knowledge of that prototype instance.

http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch04s04.html#beans-factory-scopes-prototype

like image 32
Francisco Spaeth Avatar answered Nov 08 '22 19:11

Francisco Spaeth