By default, Spring “application context” eagerly creates and initializes all ‘singleton scoped‘ beans during application startup itself. It helps in detecting the bean configuration issues at early stage, in most of the cases. But sometimes, you may need to mark some or all beans to be lazy initialized due to different project requirements.
Spring provides two easy ways to configure lazy initialization of beans based on which kind of configuration you are employing i.e. XML based configuration or java based configuration.
Table of Contents 1. Lazy initialized beans in Java configuration 2. Lazy initialized beans in XML configuration
1. @Lazy initialized beans – Java configuration
1.1. @Lazy load specific bean
To lazy load only specific beans, use @Lazy
annotation along with @Bean
annotation in java config.
import org.springframework.context.annotation.Lazy; @Configuration public class AppConfig { @Lazy @Bean public EmployeeManager employeeManager() { return new EmployeeManagerImpl(); } }
1.2. Lazy load all beans
To lazy load all beans, use @Lazy
annotation along with @Bean
annotation in java config.
import org.springframework.context.annotation.Lazy; @Lazy @Configuration public class AppConfig { @Bean public EmployeeManager employeeManager() { return new EmployeeManagerImpl(); } }
1.3. @Autowired lazy beans
Generally, beans are injected into other components using @Autowired annotation. In this case, we must use the lazy annotation at both places:
- The bean definition which you want to lazy load
- The place it is injected along with @Autowired annotation
@Lazy @Service public class EmployeeManagerImpl implements EmployeeManager { // }
@Controller public class EmployeeController { @Lazy @Autowired EmployeeManager employeeManager; }
Without using @Lazy
annotation at both places, it will not work.
2. Lazy initialized beans in XML configuration
2.1. Lazy load specific beans only
To enable lazy loading for specific beans, use lazy-init=”true” attribute on bean definitions in bean configuration xml files.
<beans> <bean id="employeeManager" class="com.howtodoinjava.spring.service.impl.EmployeeManagerImpl" lazy-init="true"/> <beans>
2.2. Lazy load all beans globally
To enable lazy loading for all beans, use default-lazy-init=”true” attribute on beans
tag in bean configuration xml files.
<beans default-lazy-init="true"> <bean id="employeeManager" class="com.howtodoinjava.spring.service.impl.EmployeeManagerImpl" /> <beans>
3. Spring lazy loading demo
Let’s see the code of bean, we are trying to lazy load.
@Lazy @Service public class EmployeeManagerImpl implements EmployeeManager { @Override public Employee create() { Employee emp = new Employee(); emp.setId(1); emp.setName("Lokesh"); return emp; } @PostConstruct public void onInit(){ System.out.println("EmployeeManagerImpl Bean is Created !!"); } }
I have put the @PostConstruct
annotation to detect when bean is created.
Lets initialize the application context with –
3.1. Without Lazy loading
import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.howtodoinjava.spring.model.Employee; import com.howtodoinjava.spring.service.EmployeeManager; public class Main { public static void main( String[] args ) { ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); System.out.println("Bean Factory Initialized !!"); EmployeeManager empManager = ctx.getBean(EmployeeManager.class); Employee emp = empManager.create(); System.out.println(emp); } }
Program output.
EmployeeManagerImpl Bean is Created !! Bean Factory Initialized !! Employee [id=1, name=Lokesh]
Here, first bean has been created and initialized before the bean factory got fully initialized.
3.2. With Lazy loading
Bean Factory Initialized !! EmployeeManagerImpl Bean is Created !! Employee [id=1, name=Lokesh]
After enable bean lazy loading, bean factory first for fully initialized. Later when we requested the EmployeeManager
bean, factory then created the instance and returned it.
Drop me your questions in comments section related to difference between lazy loading and eager loading in Spring.
Happy Learning !!
Hi Lokesh,
I am learning Spring and I am not able to think of a use case for using lazy loading can you help me with it?
how can we make dispatcher servlet as lazy loading in spring mvc
oh god.. spring 5 and configuration in XML, wtf dude
Post has both versions of config. You can ignore the XML config and that’s perfectly normal. Trust me.
Hello Lokesh,
I wanted to tell you that you made a typo in your titles, you should invert the titles because it is confusing:
Instead of that:
a) “With Lazy loading” enabled
b) “Without Lazy loading” enabled
Copy paste that:
a) “Without Lazy loading” enabled
b) “With Lazy loading” enabled
Best regards,
Pietr
Thanks for taking time to report this. Much appropriated. Thank you !!
Hi Lokesh,
Suppose if I pass wrong properties to a bean,
And then don’t refer to this bean in the java code, why do I get error? If it was lazy initiated shouldn’t Spring IoC not bother about xyz bean while initializing ApplicationContext? And I should get error only when I try creating an object of abc class.
There will not be any error if this bean “xyz” is not passed as dependency into any other eager-initialized bean. In such case, to validate/initialize the eager-initialized bean, spring will initialize this lazy init bean as well.
If “xyz” bean is not used as dependency anywhere, then there will not be any error.
hello Lokesh Sir
I am little bit confuse to take applicationCcontext Ioc container that suppose i have mark lazy-init true in any bean(bean name abc) and other bean are mark false and if i request to get abc bean from applicationContext Ioc container then it will be initialized at a time of container load or when we request for that bean then it will be load.please put your comment.
Thanks
It will be initialized on demand. Not in container initialization.
Hi Lokesh,
I am getting little confused after reading the first line of this blog which states that — “By default, Spring bean factory eagerly creates and initializes all ‘singleton scoped‘ beans during application startup itself.”
Consider below code, After execution of this code I am getting below output in console logs:
Output:—–
Hello World!
Mar 02, 2018 11:21:20 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from file [D:\TUTORIAL\springcoretutorial\spring.xml]
TestApplication Object hashCode :::: 12122356
My question/confusion point is, after printing “Hello World!”, when getBean() method is called then it goes to load bean definition and then it provides result (which is lazy initialization). I don’t know my understanding is correct or not. Please put your comments.
Thanks
You have too sharp eyes. Thanks for catching it. Fact is that “
BeanFactory
uses lazy initialization approach whereasApplicationContext
uses eager initialization approach” i.eBeanFactory
creates a singleton bean only when it is requested from it butApplicationContext
creates all singleton beans at the time of its own initialization.