File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Spring and the fly likes How to create NON SINGLETON beans in Spring ? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Frameworks » Spring
Bookmark "How to create NON SINGLETON beans in Spring ?" Watch "How to create NON SINGLETON beans in Spring ?" New topic
Author

How to create NON SINGLETON beans in Spring ?

omkar patkar
Ranch Hand

Joined: Aug 25, 2005
Posts: 231
Hi all,

Few weeks back, i have started learning spring.
I was just trying out a program, to create non-singleton beans. But i am not getting expected results.
Can someone please tell me why is it so ? ... here are the details of my test program.

Background:-
--------------------------
I am using Spring 3 M3 version and Java 6


About the Program: -
--------------------------
I have created a POJO class by the name "Task".
Task.java has 2 properties : -
1) taskName of type java.lang.String
2) taskCreationDate of type java.util.Date

The class looks as follows: -


Now, in the spring -config file, i create 2 instances of the Task class with ids as "task1" and "task2".
I create another bean using spring which is of type java.util.Date ... in other words, it will give me current date and time.
Id of this bean is "currentDateTime", and this bean has been declared with scope as "prototype" ... which should indicate to container
that different instances should be created.
Now these different instances are injected in the "taskCreationDate" property of the "Task" POJO declartively in the xml file.
In order to find out if different instances of date are created, i purposely give a delay of 2 seconds between creation of "task1" and "task2" objects.
But the output shows that, same date is used for the two task objects.
However, in the end if i output the value held by the "currentDateTime" bean, then the delay of 2 seconds is clearly visible.

The config file looks as follows : -


The Tester.java is simple standalone static void main class that will test the creation of the non singleton beans.
It looks as follows: -




..... the output looks like this : -

The task >> Take Medicine << was created at >>Fri Sep 04 21:57:35 IST 2009 <<


The task >> Download movie << was created at >>Fri Sep 04 21:57:35 IST 2009 <<


Fri Sep 04 21:57:37 IST 2009


.... why am i getting unexpected output ? ... am i doing something wrong .... or how does spring create non singleton objects ?

Thanks and Regards
Omkar Patkar


Thanks and Regards
Omkar Patkar (SCJP 1.4)[url]http://javacollectionsnotes.blogspot.com[/url] | [url]http://omkar-myscjpexp.blogspot.com[/url]
Trilochan Bharadwaj
Ranch Hand

Joined: Feb 02, 2009
Posts: 100
delay's not going to matter, your context loads beans in one shot, off course the date instances will be different, you can check this by doing:


This should give you false.

Trilochan
omkar patkar
Ranch Hand

Joined: Aug 25, 2005
Posts: 231
Hi Trilochan,

Thank you for the reply.

I just checked. Yes, "false" is returned.
Even the hashcodes are different.

But then why .... same values of date ?

Still i am a bit confused. Could you please ellaborate what might be happening ?

Thanks and Regards
Omkar Patkar
Hong Anderson
Ranch Hand

Joined: Jul 05, 2005
Posts: 1936
One second for CPU is a very long time, I think it can create 1,000 Date objects in less than a second.

And when the Java executes this line:

Spring creates beans, so delay after that has no effect.


SCJA 1.0, SCJP 1.4, SCWCD 1.4, SCBCD 1.3, SCJP 5.0, SCEA 5, SCBCD 5; OCUP - Fundamental, Intermediate and Advanced; IBM Certified Solution Designer - OOAD, vUML 2; SpringSource Certified Spring Professional
omkar patkar
Ranch Hand

Joined: Aug 25, 2005
Posts: 231
Thank you Kengkaj

But in that case,

The line : -



should also return same date... in fact it is called immediately after creation of task2.

So unlike, there is a delay of 2 seconds in creation of task2 there is ideally no delay at all between creation of task2 and currentDateTime.

But the SOP for currentDateTime returns a delay of 2 seconds. That is what confused me.

How does Spring handle instantiation of objects when they are declared as prototype ?

Thanks and Regards
Omkar Patkar
Hong Anderson
Ranch Hand

Joined: Jul 05, 2005
Posts: 1936
omkar patkar wrote:Thank you Kengkaj

But in that case,

The line : -



should also return same date... in fact it is called immediately after creation of task2.

That is because you use prototype scope for currentDateTime, Spring will create new instance every time you use getBean.
It should be crystal clear now.
omkar patkar
Ranch Hand

Joined: Aug 25, 2005
Posts: 231
Thank you Kengkaj ... i think i got your point.

I slightly amended the spring config file, and i got the expected results that is different dates for the Task objects.

What i did is, i changed the scope of the bean declarations of "task1" and "task2" objects to "prototype" and i got the expected result.
Or,
If i add the "lazy-init" attribute as "true" to the bean declaration of "task1" and "task2" objects, even then i get expected results.

From this i have concluded that, Spring instantiates all singleton beans FIRST and keeps them in the container.
And only when, call is made for instantion of non singleton beans, they are instantiated.

Base on this ... in our example, following things might have happened in sequence.
1) When context object was created, at that time, it loaded definitions of all singleton beans and tried to instantiate them.
2) In this process, the container came to know that "task1" and "task2" objects are SINGLETON beans.
3) Container comes across bean definition of "task1" first, so it tries to instantiate it.
4) During instantiation, it realizes there is dependency on another bean "currentDateTime" which is NON SINGLETON. So it creates a date object and assigns
reference to the "taskCreationDate" property of the "task1".
5) Similary container comes across bean definition of "task2", so it tries to instantiates it.
6) During instantiation, it realizes there is dependency on another bean "currentDateTime" which is NON SINGLETON. So it creates a date object and assigns
reference to the "taskCreationDate" property of the "task2".
7) The date objects created in step 4) and 6) are different as they differ in milliseconds which is not visible in the "toString()" method of Date class. Steps 2) to 3) and steps 5) to 6) were executed at load time, and hence there is hardly any difference in the values of date objects of the two classes.
8) When the "task1" object is asked to the container using the getBean(), it returns the one it created at load time.
9) After 2 seconds, "task2" object is asked to the container using the getBean(), it returns the one it created at load time, that is the reason why visibly there was no difference of 2 seconds in the date of the two task objects.
10) When "currentDateTime" object is asked to the container using getBean(), container knows, this is a "prototype" or "NONSINGLETON" bean, so it again creates a new instance... but by now 2 seconds have passed by since the last time it created a date object. That is the reason why the latest access of
"currentDateTime" displays a delay of 2 seconds.


The above life cycle was changed when the "task1" and "task2" objects were declared as "prototype" or there "lazy-init" was declared as "true".
By doing so, they were not instantiated at load time, ... instead they were instantiated only when requested at the call of "getBean()"
and hence the result were as expected.

I hope this understanding of mine is correct.
Kindly correct me if i am wrong.

Thanks and Regards
Omkar Patkar
omkar patkar
Ranch Hand

Joined: Aug 25, 2005
Posts: 231
Hello guys,

I would like to share, one more interesting thing i came across, while trying out further more on this example.

As we had analyzed, the instantiation of singleton beans by container at load time is done ONLY by APPLICATIONCONTEXT implementation of spring container.
Simple implementations of BEANFACTORY (.... i.e., NON-APPLICATIONCONTEXT based containers) will instantiate the beans only when requested, without even
specifying the "scope=prototype" or "lazy-init=true" for the bean declaration of the "task1" and "task2".

In other words, as per my first post, (the program in which i was getting same date time stamp for the 2 task objects), if instead of using ApplicationContext as the container, if i use the XMLBeanFactory (simple implementation of BeanFactory), I will get different timestamps for the task objects without the need of me declaring the "task1" and "task2" beans as "scope=prototype" or "lazt-init=true".



Thanks and Regards
Hong Anderson
Ranch Hand

Joined: Jul 05, 2005
Posts: 1936
ApplicationContext implementations by default pre-instantiate singleton beans.
 
 
subject: How to create NON SINGLETON beans in Spring ?
 
Similar Threads
Exception with Range - org.springframework.beans.TypeMismatchException
Mybatis + spring don't work.
CGLib error in "Before Advice" case
Spring with generics
Get error in standalone AOP prog