Spring @Lazy Loaded Beans

By default, Spring ApplicationContext eagerly creates and initializes all ‘singleton scoped‘ beans during the application startup. In most cases, it helps detect the bean configuration issues at an early stage. But sometimes, we may need to mark some or all beans to be lazily initialized due to different project requirements.

1. @Lazy Initialization

Spring allows lazy beans creation in two ways:

  • Applied to specific beans
  • Configure the behavior globally

1.1. Only Specific Beans

To lazy load only specific beans, use @Lazy annotation along with @Bean annotation while declaring the bean.

@Configuration
public class AppConfig {

    @Lazy
    @Bean
    public EmployeeManager employeeManager() {
        return new EmployeeManagerImpl();
    }

}

1.2. Global Configuration

To lazy load all beans, use @Lazy annotation along with @Configuration annotation at the class level.

@Lazy
@Configuration
public class AppConfig {

    @Bean
    public EmployeeManager employeeManager() {
        return new EmployeeManagerImpl();
    }

    //other beans in this class are also lazy loaded
}

The above configurations are equivalent to the XML-based configuration‘s default-lazy-init=“true” attribute.

<beans default-lazy-init="true">
   
  <bean id="operations" class="com.howtodoinjava.spring.beans.Operations"></bean>
   
</beans> 

2. Autowiring @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 we 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, autowiring will not work.

3. Demo

Let’s see the code of EmployeeManager, we are trying to lazy load.

//@Lazy   -- Uncomment for lazy bean intializations
@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 the bean is created. Let us initialize the application context with:

3.1. Without Lazy Loading

ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

System.out.println("Bean Factory Initialized !!");

EmployeeManager empManager = ctx.getBean(EmployeeManager.class);
Employee emp = empManager.create();	

Notice the program output. Here, the bean has been created and initialized before the bean factory is fully initialized.

EmployeeManagerImpl Bean is Created !!
Bean Factory Initialized !!

3.2. With Lazy Loading

Bean Factory Initialized !!
EmployeeManagerImpl Bean is Created !!

After enabling bean lazy loading, the bean factory is first fully initialized. Later when we requested the EmployeeManager bean, the factory then created the instance and returned it.

4. Conclusion

In this Spring tutorial, we learned about the basics of @Lazy annotation and how to use it for lazy bean initializations. we also saw an example of lazy loaded beans after the application context is fully initialized.

Drop me your questions in the comments section about the difference between lazy and eager loading in Spring.

Happy Learning !!

Sourcecode Download

Comments

Subscribe
Notify of
guest
4 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.