Wednesday, September 25

Spring framework and Singleton design pattern , Singleton vs prototype , Method injection in Spring

Spring framework and Singleton design pattern , Singleton vs prototype , Method injection in Spring







Singleton design pattern

In spring configuration file , when we define bean scope attributes, value is set as Singleton to instance control the Bean instances to only one instance.

&lt bean id=”manager” class=”com.org.company.Manager” scope="singleton” &gteq


In above definition Manager is defined as singleton

But one should note that spring here defines the singleton only in scope of current application-context . So concept of singleton per application Context is followed in spring . If same class is loaded in two different application-context two instances will be created , one for each application context.


Scope attribute can have below values

singleton
    Scopes a single bean definition to a single object instance per SpringBeanFactory /applicationContext.

prototype
    One bean per object instance. .

request
       Instance per request . Every  HTTP request will have its own instance created and will live till request is valid.

session
      Instance per session. Every  HTTP session will have its own instance created and will live till request is valid.

global session   
    Scopes a single bean definition to the lifecycle of a global HTTP Session. This is only valid  in case of portlet context.



Also , concept of singleton in spring is different from that of GOF . GOF says singleton means single instance per classloader while spring says single instance per container. BeanFactory or applicationContext is referred as container .

Various ways to define singleton in spring are :

&lt bean id=”manager” class=”com.org.company.Manager” scope="singleton” &gteq
&lt bean id=”manager” class=”com.org.company.Manager” &gteq
&lt bean id=”manager” class=”com.org.company.Manager” singleton="true" &gteq
Default scope of bean is singleton. So if scope attribute is not define Bean is automatically singleton.


So question arise : Where to use singleton and where to use prototype

How can you decide that ?

 State of the instance can be used to decide that. Singleton bean is shared among multiple request So data is shared here . Means If data is a request specific and does not require sharing  , we can not go with singleton approach as with that approach we won't be able to maintain different states for different beans of same class. Conclusively As a rule of thumb We should be governed by rule : for stateful bean we should defined it with prototype (each bean instance will have its own copy with its own data) . For stateless bean we can define it as singleton scoped as in that case bean does not maintain any request specific state and can be shared among multiple request to cater a set of common behavior and shared data.


If we say

&lt bean id=”manager” class=”com.org.company.Manager” singleton="false" &gteq
It is prototype


OR If we say 

& ltbean id=”manager” class=”com.org.company.Manager” scope="prototype” &gteq  

It is prototype



One more important thing to know is that a bean in prototype scope has to be explicitly destructed by user code after use . Container does not keep the reference of prototype bean after instantiation . It just create and decorate or assemble the bean ,handle it to client and forget the bean. Now its user code's responsibility to write it's destruction mechanism . So once it is used client code should release it and all heavy objects associated with it.Generally we define bean post-processor method to do that clean up.





If a singleton bean has dependency on prototype bean How It would be resolved if any time a new prototype bean  is required and should be associated with singleton bean . Singleton bean is created once for ever and dependencies are associated at creation time So whatever the dependency (here prototype) will not be updated again and again.

So what is the solution to overcome this



-->

Spring provides concept of method injection .

How does method injection works and resolve this problem ?


Let's understand this with an example :



public abstract class Manager{

   public Object process() {
     
      Develoerdeveloper = retrieveDeveloper();
     

   }

   
   protected abstract Develoer retrieveDeveloper();
}




&lt!--  prototype  -->
&ltbean id="command" class="Develoer" scope="prototype">

&lt/bean>

&ltbean id="manager" class="Manager">
  &ltlookup-method name="retrieveDeveloper" bean="Develoer"&gteq
&lt/bean>

 


What is happening here?

Manager is singleton class here and has a dependency on Developer bean , which is defined as prototype bean.So Developer needs to be loaded again and again depending upon changing bean data as Developer is stateful instance.
So we are using here , method injection technique. retrieveDeveloper is lookup method that look up for Developer bean as and when method is invoked and associate the new Developer bean as and when created. Thus keeps the Singleton bean associated with required and updated instance of Developer bean all the time.












No comments:

Post a Comment