Search This Blog

Sunday 1 July 2012

Lazily loading beans ?

One of the differences between BeanFactory and ApplicationContext is their method of loading beans. The beanfactory lazily loads beans. It creates the bean only when the getBean() method is called.
The ApplicationContext on the other hand preloads all singleton beans upon context start up. If we check the logs for the application context initialization:
INFO: Loading XML bean definitions from class path resource [lazy-beans.xml]
Feb 23, 2012 10:05:19 PM org.springframework.beans.factory.support.
DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.
support.DefaultListableBeanFactory@d80be3: defining beans [dBean1,dBean2]; 
root of factory hierarchy
As can be seen the beans are loaded in a non-lazy manner.However this behavior can be changed. To test the same I created a dummy class to act as bean.
public class DummyBean {
    
    public DummyBean() {
        System.out.println("object created " + this);
    }
}
The bean declarations for the above class would be as follows:
<?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" 
    default-lazy-init="true">

    <bean id="dBean1" class="com.start.DummyBean" />
    <bean id="dBean2" class="com.start.DummyBean" />
</beans>
The "default-lazy-init" attribute tells the application context if its needs to lazily load the beans. The default value of the attribute is false. Which makes the ApplicationContext non lazily load the beans. If we were to test the code
public class TestLazy {

    public static void main(String[] args) throws FileNotFoundException {
        final ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "lazy-beans.xml");
        System.out.println(applicationContext);
    }
}
The output of the above code is :
org.springframework.context.support.ClassPathXmlApplicationContext@54172f:
 startup date [Fri Feb 24 00:37:46 IST 2012]; root of context hierarchy
If we were to change the value to false:
object created com.start.DummyBean@111a775
object created com.start.DummyBean@12d3205
org.springframework.context.support.ClassPathXmlApplicationContext@54172f:
 startup date [Fri Feb 24 00:42:19 IST 2012]; root of context hierarchy
As can be seen, the Application Context created the beans as a part of the context initialization code. Spring provides the option to make specific beans lazy too.
<bean id="dBean1" class="com.start.DummyBean" lazy-init="true"/>
<bean id="dBean2" class="com.start.DummyBean" />
The "lazy-init" attribute is set to value "true". This means that "dBean1" will only be loaded lazily. "dBean2" on the other hand is loaded at initialization itself. The output of the test code is :
object created com.start.DummyBean@111a775
org.springframework.context.support.ClassPathXmlApplicationContext@54172f:
 startup date [Fri Feb 24 00:45:47 IST 2012]; root of context hierarchy
The "lazy-init" attribute takes three values - true,false and default. "default" implies that the value will be picked up from the "default-lazy-init" attribute of the beans element.
I tried to test the above beans using BeanFactory. However I was not able to pre-instantiate any beans. The beans were only created when the getBean() method was called. i.e. they were always loaded lazily.

No comments:

Post a Comment