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