Google

Feb 17, 2014

Tutorial: Understanding Spring scopes -- Singleton Vs Prototype

This posts extends Understanding Spring scopes -- Singleton Vs Prototype.

Step 0: Spring Jar files required. You can use maven or download and add to the classpath.



Step 1: Define the Java interface for Dao class.


package com.mycompany.understanding.spring;

public interface MyDao {
 abstract void printData();
}


Step 2: Define the Dao implementation.

package com.mycompany.understanding.spring;

public class MyDaoImpl implements MyDao {

 @Override
 public void printData() {
  System.out.println("printing data"); 
  System.out.println(this);
 }

}

Step 3: Define the Service interface.

package com.mycompany.understanding.spring;

public interface MyService {
 abstract void performTask();
}

Step 4:  Define the Service implementation into which the Dao implementation gets injected.

package com.mycompany.understanding.spring;

public class MyServiceImpl implements MyService {

 private MyDao myDao;
 
 public MyServiceImpl(MyDao myDao) {
  this.myDao = myDao;
 }

 @Override
 public void performTask() {
  System.out.println("Performing tasks .............");
  myDao.printData();
 }
}






Step 5: Use Spring context file  applicationContext.xml to wire up the dependencies. Note that both beans are defined as singleton, which is the default.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="myDaoDef" class="com.mycompany.understanding.spring.MyDaoImpl" scope="singleton"/>
    
    <bean id="myServiceDef" class="com.mycompany.understanding.spring.MyServiceImpl" scope="singleton"> 
       <constructor-arg name="myDao" ref="myDaoDef" /> 
    </bean>

</beans>


Step 6:  The runnable main class. The applicationContext.xml is bootstrapped here.

package com.mycompany.understanding.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyMainApp {
 
 public static void main(String[] args) {
  ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
  for (int i = 0; i <3; i++) {
   MyService service = (MyService) applicationContext.getBean("myServiceDef");
   System.out.println(service);
   service.performTask();
  }
 }
}

Step 7: Running the main class and comparing the results with different scopes. The for loop was created to instantiate more than one bean. Look at the memory address of the beans printed to see how many instances are created.

1.When both beans are singleton:

com.mycompany.understanding.spring.MyServiceImpl@7188eb7
Performing tasks .............
printing data
com.mycompany.understanding.spring.MyDaoImpl@5d419404
com.mycompany.understanding.spring.MyServiceImpl@7188eb7
Performing tasks .............
printing data
com.mycompany.understanding.spring.MyDaoImpl@5d419404
com.mycompany.understanding.spring.MyServiceImpl@7188eb7
Performing tasks .............
printing data
com.mycompany.understanding.spring.MyDaoImpl@5d419404

Only MyDaoImpl@5d419404 and MyServiceImpl@7188eb7 are created.

2. When both beans are prototypes: now change both scopes to "prototype" in the applicationContext.xml and retrun.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="myDaoDef" class="com.mycompany.understanding.spring.MyDaoImpl" scope="prototype"/>
    
    <bean id="myServiceDef" class="com.mycompany.understanding.spring.MyServiceImpl" scope="prototype"> 
       <constructor-arg name="myDao" ref="myDaoDef" /> 
    </bean>

</beans>


You can see 3 instances of service and 3 instances of Dao are created.

com.mycompany.understanding.spring.MyServiceImpl@64c53235
Performing tasks .............
printing data
com.mycompany.understanding.spring.MyDaoImpl@4e636942
com.mycompany.understanding.spring.MyServiceImpl@8dc488c
Performing tasks .............
printing data
com.mycompany.understanding.spring.MyDaoImpl@361ee3df
com.mycompany.understanding.spring.MyServiceImpl@2602613b
Performing tasks .............
printing data
com.mycompany.understanding.spring.MyDaoImpl@663d7bfb


3. When Service bean is singleton and Dao bean is prototype

com.mycompany.understanding.spring.MyServiceImpl@7188eb7
Performing tasks .............
printing data
com.mycompany.understanding.spring.MyDaoImpl@5d419404
com.mycompany.understanding.spring.MyServiceImpl@7188eb7
Performing tasks .............
printing data
com.mycompany.understanding.spring.MyDaoImpl@5d419404
com.mycompany.understanding.spring.MyServiceImpl@7188eb7
Performing tasks .............
printing data
com.mycompany.understanding.spring.MyDaoImpl@5d419404


You can only see 1 instance of service bean and 1 instance of prototype bean. This is not desired as in some scenarios you want to create new prototype bean again and again. This is where lookup-method comes in handy.

4. When Service bean is prototype and Dao bean is singleton.

com.mycompany.understanding.spring.MyServiceImpl@5d419404
Performing tasks .............
printing data
com.mycompany.understanding.spring.MyDaoImpl@7c5cc270
com.mycompany.understanding.spring.MyServiceImpl@528f1577
Performing tasks .............
printing data
com.mycompany.understanding.spring.MyDaoImpl@7c5cc270
com.mycompany.understanding.spring.MyServiceImpl@2fca61f9
Performing tasks .............
printing data
com.mycompany.understanding.spring.MyDaoImpl@7c5cc270


You can see 3 instances of the service beans and only 1 instance of the dao bean. Simple examples like this can clarify the concepts.

Scenario 3 is not desired as in some scenarios, and you want to create new prototype bean again and again. This is where lookup-method comes in handy. I will cover this in the next post.

Labels: ,

2 Comments:

Blogger Vikram Jada said...

Hi Sir,

In the above example when the DAO is made prototype but the service is singleton why only one instance of the DAO bean is created but on the other hand when you make the service as prototype multiple instances of services are created on running the main.

10:44 PM, March 25, 2014  
Blogger Arulkumaran Kumaraswamipillai said...

DAO gets injected into Service. There is only a single instance of service, which takes a single instance of DAO when initialized. When you have Service as prototype, each thread will have its own instance, and same DAO gets injected into each new instance of service.

11:42 PM, March 25, 2014  

Post a Comment

Subscribe to Post Comments [Atom]

<< Home