Home » BeanFactory lazy loading

BeanFactory lazy loading

  • by
BeanFactory lazy loading

1. Overview

In this article, we will learn about the lazy loading of beans in BeanFactory.

2. BeanFactory

The Spring framework comes with two IOC containers:

  1. BeanFactory
  2. ApplicationContext

The BeanFactory is the root interface for accessing a Spring bean container whereas ApplicationContext extends the BeanFactory and its functionalities.

The Spring IOC container gets its instructions on what bean objects to instantiate, configure, and assemble by reading configuration metadata. We can represent the configuration metadata using any of the below:

  1. XML configuration
  2. Annotation-based configuration
  3. Java-based configuration.

It lets you express the objects that compose your application and the rich interdependencies between those objects. See this bean instantiation article to understand more.

2.1. Bean Initialization

BeanFactory uses lazy initialization but ApplicationContext uses eager initialization. The BeanFactory creates the beans when you invoke or use the beans such as getBeans() method, whereas the ApplicationContext eagerly creates and configures all singleton beans as part of the initialization process.

This pre-instantiation is desirable because you can discover any errors in the configuration or surrounding environment immediately during application start-up, as opposed to runtime hours or even days later.

When this behavior is not desirable, you can prevent pre-instantiation of a singleton bean by marking the bean definition as lazy-initialized. You can refer to this article to learn more about lazy initialization.

2.2. BeanFactory lazy loading

Let’s see an example to confirm the default lazy loading of beans in BeanFactory.

First, let’s create a sample class and its instance needs to be managed by the BeanFactory Spring IOC container.

We will instruct the BeanFactory to instantiate using the constructor. Note that we have added a print statement in the constructor to check whether the sample bean is instantiated during load time eagerly or at runtime.

public class SampleBean {
    private int value;
    public SampleBean(int value) {
        System.out.println("SampleBean initialized");
        this.value = value;
    }
    public int getValue() {
        return value;
    }
    public void setValue(int value) {
        this.value = value;
    }
}

Now, let’s create an XML configuration by defining the beans that need to be managed by BeanFactory container.

<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-2.5.xsd">
    <bean id="employee" class="com.tedblob.beanfactory.models.SampleBean">
        <constructor-arg value="1000" />
    </bean>
</beans>

In the below test case, we are loading the BeanFactory pointing to the config.xml configuration

@Test
public void testBeanFactoryLazyInitialization() {
        Resource res = new ClassPathResource("config.xml");
	BeanFactory factory = new XmlBeanFactory(res);
}

If you execute the above test case, you cannot see any “SampleBean initialized” print statement in the logs. This confirms that the BeanFactory loads the beans lazily.

Let’s modify the test case a little bit to confirm this.

@Test
public void testBeanFactoryLazyInitialization() {
	Resource res = new ClassPathResource("config.xml");
	BeanFactory factory = new XmlBeanFactory(res);
	SampleBean sampleBean = factory.getBean(SampleBean.class);
	sampleBean.getValue();
}

If you execute this test case now, the “SampleBean initialized” text will appear in the logs as invoking getBean method would initialize the bean at runtime.

3. Conclusion

To sum up, we have learned that the BeanFactory loads the beans lazily and an example to confirm the behavior. You can find code samples of this article in our GitHub repository.