Generic Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE

1. Overview

In this tutorial, we’ll see how to configure lazy initialization at the application level, starting with Spring Boot 2.2

2. Lazy Initialization

By default in Spring, all the defined beans, and their dependencies, are created when the application context is created.

In contrast, when we configure a bean with lazy initialization, the bean will only be created, and its dependencies injected, once they’re needed.

3. The Maven Dependency

In order to get Spring Boot 2.2 in our application, we need to include it in our classpath.

With Maven, we can just add the spring-boot-starter dependency:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>2.2.0.M3</version>
    </dependency>
</dependencies>

<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
    </repository>
</repositories>

Note that the repository is only necessary because we are using a milestone release for this tutorial.

4. Enable Lazy Initialization

Spring Boot 2.2 introduces the spring.main.lazy-initialization property, making it easier to configure lazy initialization across the whole application.

Setting the property value to true means that all the beans in the application will use lazy initialization.

Let’s configure the property in our application.yml configuration file:

spring:
  main:
    lazy-initialization: true

Or, if it’s the case, in our application.properties file:

spring.main.lazy-initialization=true

This configuration affects all the beans in the context. So, if we want to configure lazy initialization for a specific bean, we can do it through the @Lazy approach.

Even more, we can use the new property, in combination with the @Lazy annotation, set to false.

Or in other words, all the defined beans will use lazy initialization, except for those that we explicitly configure with @Lazy(false).

5. Run

Let’s create a simple service that will enable us to test what we just described.

By adding a message to the constructor, we’ll know exactly when the bean gets created.

public class Writer {

    private final String writerId;

    public Writer(String writerId) {
        this.writerId = writerId;
        System.out.println(writerId + " initialized!!!");
    }

    public void write(String message) {
        System.out.println(writerId + ": " + message);
    }
    
}

Also, let’s create the SpringApplication and inject the service we’ve created before.

@SpringBootApplication
public class Application {

    @Bean("writer1")
    public Writer getWriter1() {
        return new Writer("Writer 1");
    }

    @Bean("writer2")
    public Writer getWriter2() {
        return new Writer("Writer 2");
    }

    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(Application.class, args);
        System.out.println("Application context initialized!!!");

        Writer writer1 = ctx.getBean("writer1", Writer.class);
        writer1.write("First message");

        Writer writer2 = ctx.getBean("writer2", Writer.class);
        writer2.write("Second message");
    }
}

Let’s set the spring.main.lazy-initialization property value to false, and run our application.

Writer 1 initialized!!!
Writer 2 initialized!!!
Application context initialized!!!
Writer 1: First message
Writer 2: Second message

As we can see, the beans were created when the application context was starting up.

Now let’s change the value of spring.main.lazy-initialization to true, and run our application again.

Application context initialized!!!
Writer 1 initialized!!!
Writer 1: First message
Writer 2 initialized!!!
Writer 2: Second message

As a result, the application didn’t create the beans at startup time, but only when it needed them.

6. Effects of Lazy Initialization

Enabling lazy initialization in the whole application could produce both positive and negative effects.

Let’s talk about some of these, as they’re described in the official announcement of the new functionality:

  1. Lazy initialization may reduce the number of beans created when the application is starting – therefore, we can improve the startup time of the application
  2. As none of the beans are created until they are needed, we could mask issues, getting them in run time instead of startup time
  3. The issues can include out of memory errors, misconfigurations, or class-definition-found errors
  4. Also, when we’re in a web context, triggering bean creation on demand will increase the latency of HTTP requests – the bean creation will affect only the first request, but this may have a negative impact in load-balancing and auto-scaling.

7. Conclusion

In this tutorial, we configured lazy initialization with the new property spring.main.lazy-initialization, introduced in Spring Boot 2.2.

As always, the source code for this tutorial is available over on GitHub.

Generic bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE