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: Spring, Spring core
2 Comments:
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.
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.
Post a Comment
Subscribe to Post Comments [Atom]
<< Home