1. Overview
By default, Spring creates all singleton beans eagerly at the startup/bootstrapping of the application context. The reason behind this is simple: to avoid and detect all possible errors immediately rather than at runtime.
However, there’re cases when we need to create a bean, not at the application context startup, but when we request it.
In this quick tutorial, we’re going to discuss Spring’s @Lazy annotation.
2. Lazy Initialization
The @Lazy annotation has been present since Spring version 3.0. There’re several ways to tell the IoC container to initialize a bean lazily.
2.1. @Configuration Class
When we put @Lazy annotation over the @Configuration class, it indicates that all the methods with @Bean annotation should be loaded lazily.
This is the equivalent for the XML based configuration’s default-lazy-init=“true“ attribute.
Let’s have a look here:
@Lazy @Configuration @ComponentScan(basePackages = "com.baeldung.lazy") public class AppConfig { @Bean public Region getRegion(){ return new Region(); } @Bean public Country getCountry(){ return new Country(); } }
Let’s now test the functionality:
@Test public void givenLazyAnnotation_whenConfigClass_thenLazyAll() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class); ctx.refresh(); ctx.getBean(Region.class); ctx.getBean(Country.class); }
As we see, all beans are created only when we request them for the first time:
Bean factory for ...AnnotationConfigApplicationContext: ...DefaultListableBeanFactory: [...]; // application context started Region bean initialized Country bean initialized
To apply this to only a specific bean, let’s remove the @Lazy from a class.
Then we add it to the config of the desired bean:
@Bean @Lazy(true) public Region getRegion(){ return new Region(); }
2.2 With @Autowired
Before going ahead, check out these guides for @Autowired and @Component annotations.
Here, in order to initialize a lazy bean, we reference it from another one.
The bean that we want to load lazily:
@Lazy @Component public class City { public City() { System.out.println("City bean initialized"); } }
And it’s reference:
public class Region { @Lazy @Autowired private City city; public Region() { System.out.println("Region bean initialized"); } public City getCityInstance() { return city; } }
Note, that the @Lazy is mandatory in both places.
With the @Component annotation on the City class and while referencing it with @Autowired:
@Test public void givenLazyAnnotation_whenAutowire_thenLazyBean() { // load up ctx appication context Region region = ctx.getBean(Region.class); region.getCityInstance(); }
Here, the City bean is initialized only when we call the getCityInstance() method.
3. Conclusion
In this quick tutorial, we learned the basics of Spring’s @Lazy annotation. We examined several ways to configure and use it.
As usual, the complete code for this guide is available over on GitHub.
Image may be NSFW.Clik here to view.
Clik here to view.