Partner – Microsoft – NPI (cat= Spring)
announcement - icon

Azure Spring Apps is a fully managed service from Microsoft (built in collaboration with VMware), focused on building and deploying Spring Boot applications on Azure Cloud without worrying about Kubernetes.

And, the Enterprise plan comes with some interesting features, such as commercial Spring runtime support, a 99.95% SLA and some deep discounts (up to 47%) when you are ready for production.

>> Learn more and deploy your first Spring Boot app to Azure.

You can also ask questions and leave feedback on the Azure Spring Apps GitHub page.

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 on GitHub.

Course – LS (cat=Spring)

Get started with Spring and Spring Boot, through the Learn Spring course:

>> THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.