destroy-method not invoked on beans registered as prototype - spring

I have a bean registered as singleton and init-method and destroy-method defined on it. I am accessing the bean and can see the calls being made to both the methods. However, on changing the scope to prototype the destroy-method is not invoked.
I am not getting the rationale behind this.

Read the documentation:
In contrast to the other scopes, Spring does not manage the complete lifecycle of a prototype bean: the container instantiates, configures, and otherwise assembles a prototype object, and hands it to the client, with no further record of that prototype instance. Thus, 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.
And that's quite logical: your application could ask for new instances of prototype beans every 10 milliseconds, do something with the bean, and then let it go out of scope. If Spring had to destroy() them when the application shuts down, it would have to keep a reference to every created prototype bean, preventing them to be garbage-collected, and thus causing a memory leak.

Related

How to instantiate Spring bean with custom scope and #Autowired dependencies?

In our project, we use Spring request scoped beans. Now we've a requirement to support async requests and request scoped beans don't work for child threads. I'm aware of RequestContextFilter and it's "support" for async but it appears that RequestContextFilter expects the main thread to wait for the child threads to finish, which isn't the case for us. Our main thread immediately returns after spawning new threads using #Async annotation and DispatcherServlet clears out the RequestContextHolder. Thus when the child threads get to the point where they need a request scoped bean, #Autowired fails.
I'm also aware of SimpleThreadScope but it doesn't clean up thread-local attributes and in a thread-pooling situation, is not only dangerous to use but downright useless.
What I need is a custom scope. So far, I've found 3 useful examples but all of them fall short in that the beans they instantiate as part of the custom scope are plain POJOs without any dependencies. Needless to say that's non-existent in a real life application. Can anyone suggest a way to instantiate custom scoped beans that have #Autowired dependencies on beans from other scopes?
What I found so far:
https://github.com/spring-by-example/spring-by-example/tree/master/modules/sbe-thread-scope/src/main/java/org/springbyexample/bean/scope/thread
https://github.com/billkoch/spring-async-mdc
Spring Bean Custom Scope JMS
Continuing the discussion from the other question's answer here...
See the Spring Documentation about scoped beans as dependencies.
.
I'm referring to the <aop:scoped-proxy/> which is what the link points to. Each time the autowired field is referenced, your custom scope's get() method is called to lookup the instance based on some criteria.
.
I understand I can look up the dependencies (though unsure how, a scope isn't a bean, perhaps I need to pass application context during instantiation?). What I don't understand is how to inject those dependencies into my bean if those're marked #Autowired? Or are you saying the custom scoped bean shouldn't have #Autowired dependencies?
It works automatically; Spring injects a proxy for the bean and the scope.get() is invoked on every method call on that bean, returning the specific instance you want in the context of the current invocation.
Take a look at the AbstractRequestAttributesScope to see how it works (in that case, gets the instance from the HTTP Request and, if it doesn't exist, creates it).
So, your code calls foo() on the proxy; the framework calls the scope to get the desired instance and then calls foo() on that instance.
The exposed methods you wish to call must either be on an interface or not declared final.

Spring #PreDestroy method

I found out that #PreDestroy only work with singleton scoped bean. I was thinking what could go wrong if we use it with prototype scoped bean. Anything at all??? I dont think so. I think this is just not implemented in spring as they would have to keep the references to all the beans created. Tell me if i am wrong
Spring can only initialize/destroy beans it also controllers and basically prototype scoped beans aren't under the control of spring (after construction). It doesn't know when it is cleaned up, destroyed or what so ever. As such the #PreDestroy method isn't callable for prototype beans (as they do not have a clearly defined lifecycle like singletons or request scoped beans).
For "prototype" scoped beans, Spring does not call the #PreDestroy method.
Here is the answer from the Spring reference manual. Section 7.5.2
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-factory-scopes-prototype
In contrast to the other scopes, Spring does not manage the complete lifecycle of a
prototype bean: the container instantiates, configures, and otherwise assembles a
prototype object, and hands it to the client, with no further record of that prototype
instance.
Thus, 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.
The #PreDestroy annotation does not belong to Spring, it’s located in the jsr250-api library jar under javax.annotation package.
By default, Spring will not aware of the #PreDestroy annotation. To enable it, you have to either register CommonAnnotationBeanPostProcessor or specify the <context:annotation-config /> in bean XML configuration file.

Use/Purpose of beans in Spring

Could someone give an overview or a summary of what the purpose of beans in a Spring framework context?
I understand the standard Java bean (no arg constructor, getters/setters, often serialized), but the Spring bean purpose seems to be different.
Is it a way of implementing the Singleton design pattern (one instance, for like factory classes) in a simple, reusable fashion?
I've mainly used Spring with annotations, but I feel I need to grasp this in order to understand Spring.
Thanks!
Beans are objects that form the backbone of the application.
A bean is simply an object that is instantiated, assembled and otherwise managed by a Spring IoC container; other than that, there is nothing special about a bean.It is in all other respects one of probably many objects in your application.
Spring beans are defined in a spring configuration file or by using annotations, instantiated by the Spring container, and then injected into your application.
Spring beans will not be singleton design pattern until you explicitly make them to be.The singleton design pattern and the spring scope 'singleton' are different things.You can define different bean scopes depending on your requirements.
The scopes could be :
singleton – Return a single bean instance per Spring IoC container
prototype – Return a new bean instance each time when requested
request – Return a single bean instance per HTTP request.
session – Return a single bean instance per HTTP session.
globalSession – Return a single bean instance per global HTTP
session.
The default scope is singleton.
I understand the standard Java bean (no arg constructor,
getters/setters, often serialized), but the Spring bean purpose seems
to be different.
You mean always serialized. Why do you think the purpose seems different?
In the end, you write classes. A lot of time these are POJOs, Plain Old Java Objects. Sometimes you implement an interface or extend a class, but its all just classes.
Beans are just classes. Don't overcomplicate it.
Now Spring might take your beans (classes) and manage them for you via any of a number of policies (prototype, singleton) but that doesn't change what a bean is, it speaks to how Spring manages the bean.
To understand best, you should get familiar with dependency injection. In a few words dependency injection allows you to use objects, or services without explicitly creating them (of course, it gives other benefits, but let's focus on the question). This is achieved by maintaining a dependency container that is - roughly said - a collection of beans.
A bean is a service/component you use in your application. Unlike the EJB, with Spring the bean is not constrained to constructor arguments or specific annotations (especially if you use xml contexts). You register a bean with a container (by defining a context), and when you require it, the container will provide you with an instance of that bean. In order to create the bean, the container examines its class and constructors, and uses any other registered beans within that context, to call the appropriate constructor or property setter.
You can configure a bean to be a singleton - this is not a singleton as in the design pattern term. Singleton beans are created once within the container, and the same instance is used whenever the bean is requested from that container. You can also use the prototype scope to force the container to create a new instance each time.

Spring injection and object instantiation

I am trying to better understand Spring instantiation of beans. To illustrate my doubts, let's assume we have a Service class being wired in a Controller, here are the questions:
How will Spring manage the lifecycle
of the Controller? Will a new object
be created per request?
Once a Service is instantiaded and
wired to a Controller, will Spring
re-use that object reference to wire
it in to other beans?
Like Servlets, Controllers' lifecycle spans beyond requests. All of controllers in the application are instantiated only once when application is started; afterwards those objects are re-used to service all requests.
As Bozho pointed out, by default all beans are in singleton scope, therefore they will be re-used everywhere, unless specified otherwise.
The default scope is singleton, which means beans will be re-used (i.e. 1) no, a new object will not be created per request, and 2) yes, the object reference will be reused).
This can all be configured. Have a look at http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes.
It all depends on the bean scope. By default all beans are in singleton scope - that is, they are instantiated by the container only once.
If you specify #Scope("request") (or the xml equivalent) then the same service object (singleton) will be injected in all instances of the request-scoped controller. (But you rarely need request-scoped controllers)

Can the object created in IoC container be called Singleton. If not - why?

can the object created in IOC container can be called Singleton if yes why if no why?
Can anybody explain me in detail in simple words how IOC conatiner exactly manages the objects..
You can say that a spring singleton is not a singleton.
Singleton has its meaningful scope, the spring singleton scope is the spring ioc container. And the classic singleton's meaningful scope is the ClassLoader. You may find more about the distinction between these kinds of singleton here: A spring singleton is not a singleton.
Spring manage its singleton in a hashmap(Singleton Cache). When you get a bean from the spring ioc container, it first checks if the bean has already exists in the singleton cache, if does, it returns the bean from the singleton cache
Spring (and other ioc-containers) offer different scopes. One of the scopes is singleton - i.e. the container instantiates the object only once and gives / injects only one instance. Singleton is the default scope, so most of the beans are indeed singletons from the point of view of the container- i.e. they have only one instance in it.
However, there are other scopes, like prototype or the web-based request and session.
In managing the bean, the container does the following:
invokes the #PostConstruct and #PreDestroy methods (or the init and destroy methods, configured by any available means)
injects all their defined dependencies (=sets other beans existing in the container to the fields of this bean)
creates AOP aspects around the bean methods
Note: you can instantiate more than one objects of a class that is defined as as singleton bean. The container instantiates the object only once, but your code is not limited to instantiating it multiple times.
can the object created in IOC
container can be called Singleton if
yes why if no why?
Read this, from the Spring Reference.
Can anybody explain me in detail in
simple words how IOC conatiner exactly
manages the objects..
Read this, from the Spring Reference.
I use a more generic definition of a Singleton:
A Singleton is an object that is
guaranteed to be unique inside a given
scope.
This scope is the ClassLoader in the traditional singleton definition, but other possible scopes are:
Application (may be clustered and therefor classic Singleton won't help)
HTTP Session
Thread (implemented through ThreadLocals)
HTTP Request etc.
(I really like the Seam method Component.getInstance(Class, ScopeType) that lets you choose the Scope you want a singleton for.)
You might find this Google Groups thread useful.

Resources