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, it will only be created, and its dependencies will be injected once needed.
3. The Maven Dependency
In order to get Spring Boot in our application, we need to include it in our classpath.
With Maven, we can add the spring-boot-starter dependency:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>3.1.5</version>
</dependency>
</dependencies>
4. Enable Lazy Initialization
Spring Boot 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)**.*
4.1. Using SpringApplicationBuilder
Another way to configure the lazy initialization is to use the SpringApplicationBuilder method:
SpringApplicationBuilder(Application.class)
.lazyInitialization(true)
.build(args)
.run();
In the above example, we use the lazyInitialization method to control whether the application should be initialized lazily.
4.2. Using SpringApplication
Alternatively, we can also use the SpringApplication class:
SpringApplication app = new SpringApplication(Application.class);
app.setLazyInitialization(true);
app.run(args);
Here, we use the setLazyInitialization method to configure our application to be initialized lazily.
One important note to remember is that properties defined in the application property files take precedence over flags set using either SpringApplication or SpringApplicationBuilder.
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:
- Lazy initialization may reduce the number of beans created when the application is starting – therefore, we can improve the startup time of the application
- As none of the beans are created until they are needed, we could mask issues getting them in run time instead of startup time
- The issues can include out-of-memory errors, misconfigurations, or class-definition-found errors
- 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 on 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.