Lazy Initialization in Spring Boot
In this article, we’ll see how to configure the lazy initialization in the Spring Boot application. Spring Boot 2.2 introduces support for lazy initialization and makes it easier via the introduction of a new property i.e. spring.main.lazy-initialization
. When it set to true
, the bean definitions across the application will be configured to use lazy initialization. Default it sets to false
.
Lazy Initialization
In Spring by default, all the beans get created and its dependencies get injected whenever the application context is refreshed. In some cases, we need this initialization happens whenever required and for these kinds of scenarios, Spring Boot 2.2 has provided a new property to initialize been lazily and delay in injecting dependencies, as and when we need it.
Required Dependency
To enable the lazy initialization, Spring Boot 2.2 or above starter dependency must be available in project classpath.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
Enable Lazy Initialization
Lazy initialization can be enabled by setting the property spring.main.lazy-initialization=true
in the application.properties file of the Spring Boot project.
spring.main.lazy-initialization=true
Or in case of application.yaml, it can also be configured like:
spring:
main:
lazy-initialization: true
Demonstration
To see how it works, let’s create two service classes i.e ServiceX
and ServiceY
as following:
package org.websparrow.service;
public class ServiceX {
public ServiceX() {
System.out.println("ServiceX initialized!");
}
public void printSomething() {
System.out.println("ServiceX : printing something...");
}
}
package org.websparrow.service;
public class ServiceY {
public ServiceY() {
System.out.println("ServiceY initialized!");
}
public void printSomething() {
System.out.println("ServiceY : printing something...");
}
}
Also, let’s create the SpringBootLazyInitializationApp
and inject the service we’ve created before.
package org.websparrow;
import org.springframework.*;
import org.websparrow.service.*;
@SpringBootApplication
public class SpringBootLazyInitializationApp {
@Bean("serviceX")
public ServiceX getServiceX() {
return new ServiceX();
}
@Bean("serviceY")
public ServiceY getServiceY() {
return new ServiceY();
}
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication
.run(SpringBootLazyInitializationApp.class, args);
System.out.println("Application context initialized!!!");
ServiceX serviceX = applicationContext.getBean("serviceX", ServiceX.class);
serviceX.printSomething();
ServiceY serviceY = applicationContext.getBean("serviceY", ServiceY.class);
serviceY.printSomething();
}
}
Now set the spring.main.lazy-initialization=false
in the application.properties file, and run the application.
ServiceX initialized!
ServiceY initialized!
Application context initialized!!!
ServiceX : printing something...
ServiceY : printing something...
As you can see, all the beans created and injected when the application is starting up.
Let’s set the spring.main.lazy-initialization=true
in the application.properties file, and run the application again.
Application context initialized!!!
ServiceX initialized!
ServiceX : printing something...
ServiceY initialized!
ServiceY : printing something...
If you compare both results, you’ll find the application didn’t create the beans at startup, but only when it needed them.
Note: If you want to disable lazy initialization for certain beans while using lazy initialization for the rest of the application, you can explicitly set their lazy attribute to false using the
@Lazy(false)
annotation.@Bean("serviceX") @Lazy(false) public ServiceX getServiceX() { return new ServiceX(); }
Pros and Cons of using Lazy Initialization
There are multiple advantages and disadvantages of using lazy initialization in the application.
- Enabling lazy initialization can reduce the time that it takes your application to start.
- It causes the
NoClassDefFoundError
,OutOfMemoryError
exception due to not finding beans and misconfiguration. - It can delay the discovery of a problem with the application. If a misconfigured bean is initialized lazily.
- Enabling lazy initialization will result in many web-related beans not being initialized until an HTTP request is received.
Conclusion
We can say using lazy initialization reduces the startup time, inject the desired beans when needed, and while using it with Spring Boot’s dev tools it increases productivity. Also, it is useful while doing integration tests as it reduces test execution time as well while running test cases in isolation during development.