Lazy Bean’s initialization is not a new topic for Spring developers.
The spring framework supports lazy-init
from over 10 years.
By enabling lazy loading ( lazy-init="true"
) for a bean, we tell spring container to not to create that bean until it’s needed.
So, what is new in the spring boot lazy initialization feature that is introduced in the spring boot 2.0 version?.
What is new in Spring Boot Lazy Initialization
To understand the benefits of lazy initialization, let’s create a demo on spring lazy initialization.
At first, go to spring initializr and generate a new project. Don’t forget to select spring boot 2.2.0 M4 version.

Now download and extract this project and import it in eclipse or STS.
After importing the project, create two new packages and classes for controllers and services.

Inside LazyController.java
package com.codedelay.lazy.controller; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.codedelay.lazy.service.LazyService; @RestController @RequestMapping("/api") public class LazyController { private static final String TAG = "LazyController"; @Autowired private LazyService mService; @GetMapping("/welcome") public String welcomeMessage() { System.out.println(TAG + " Welcome "); return mService.welcomeMessage(); } @PostConstruct public void init() { System.out.println(TAG + " init called "); } }
LazyService.java
package com.codedelay.lazy.service; import javax.annotation.PostConstruct; import org.springframework.stereotype.Service; @Service public class LazyService { private static final String TAG = "LazyService"; public String welcomeMessage() { System.out.println(TAG + " Welcome "); return "Welcome"; } @PostConstruct public void init() { System.out.println(TAG + " init called "); } }
Now let’s run the application to see how long it takes to start our application.
2019-07-25 13:45:45.150 INFO 12824 - – [ main] c.c.l.LazyIntializationDemoApplication : Starting LazyIntializationDemoApplication on W108W438S2 with PID 12824 (C:\Codedelay\lazy-intialization-demo\lazy-intialization-demo\target\classes started by Arpit_Nanavati in C:\Codedelay\lazy-intialization-demo\lazy-intialization-demo) 2019-07-25 13:45:45.154 INFO 12824 - – [ main] c.c.l.LazyIntializationDemoApplication : No active profile set, falling back to default profiles: default 2019-07-25 13:45:46.614 INFO 12824 - – [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2019-07-25 13:45:46.625 INFO 12824 - – [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2019-07-25 13:45:46.625 INFO 12824 - – [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.21] 2019-07-25 13:45:46.764 INFO 12824 - – [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2019-07-25 13:45:46.765 INFO 12824 - – [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1535 ms LazyService init called LazyController init called 2019-07-25 13:45:46.956 INFO 12824 - – [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2019-07-25 13:45:47.148 INFO 12824 - – [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2019-07-25 13:45:47.153 INFO 12824 - – [ main] c.c.l.LazyIntializationDemoApplication : Started LazyIntializationDemoApplication in 2.472 seconds (JVM running for 2.939)
As you could see in the above logs, our application took 1535 ms to initialize and 2.472 seconds to start the app.
Did you observe that even we haven’t called REST api /api/welcome
, but spring container still initialized LazyService?
LazyService init called LazyController init called
Sometimes it is not a good idea to initialize bean until it is used.
Therefore, How can we improve the performance of the above code?
Let’s optimize the above program using spring boot lazy initialization.
To enable lazy initialization, open application.properties and below code
spring.main.lazy-initialization=true
And re-run the program.
2019-07-25 13:55:14.679 INFO 19452 - – [ main] c.c.l.LazyIntializationDemoApplication : Starting LazyIntializationDemoApplication on W108W438S2 with PID 19452 (C:\Codedelay\lazy-intialization-demo\lazy-intialization-demo\target\classes started by Arpit_Nanavati in C:\Codedelay\lazy-intialization-demo\lazy-intialization-demo) 2019-07-25 13:55:14.682 INFO 19452 - – [ main] c.c.l.LazyIntializationDemoApplication : No active profile set, falling back to default profiles: default 2019-07-25 13:55:16.080 INFO 19452 - – [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2019-07-25 13:55:16.093 INFO 19452 - – [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2019-07-25 13:55:16.093 INFO 19452 - – [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.21] 2019-07-25 13:55:16.235 INFO 19452 - – [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2019-07-25 13:55:16.235 INFO 19452 - – [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1493 ms 2019-07-25 13:55:16.399 INFO 19452 - – [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2019-07-25 13:55:16.404 INFO 19452 - – [ main] c.c.l.LazyIntializationDemoApplication : Started LazyIntializationDemoApplication in 2.227 seconds (JVM running for 2.724)
From the above logs, it is clear that spring took only 1493 ms initialization, and 2.227seconds to start the application.
You may think that there is not a huge difference in application startup.
But if there are many controllers, services, config classes are present then you will find a significant difference.
Additionally, if you notice LazyService and LazyController are not yet called.
Not let’s hit API from the browser.
in my case it is http://localhost:8080/api/welcome .
2019-07-25 14:01:35.653 INFO 9136 - – [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' 2019-07-25 14:01:35.653 INFO 9136 - – [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2019-07-25 14:01:35.820 INFO 9136 - – [nio-8080-exec-1] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2019-07-25 14:01:35.907 INFO 9136 - – [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 253 ms LazyService init called LazyController init called LazyController Welcome LazyService Welcome
As you can see, once you hit API, then only spring container will initialize process service.
Enable Lazy Initialization using @Lazy
If you don’t want to enable lazy initialization for all classes. You can also use @Lazy annotation.
public class LazyController { @Autowired @Lazy private LazyService mService;
@Service @Lazy public class LazyService {
In the above LazyController class, we have annotated LazyService property with @Lazy.
Also, we have an annotated Service class with @Lazy.
Let’s re-run the application
2019-07-25 14:07:44.751 INFO 1816 - – [ main] c.c.l.LazyIntializationDemoApplication : Starting LazyIntializationDemoApplication on W108W438S2 with PID 1816 (C:\Codedelay\lazy-intialization-demo\lazy-intialization-demo\target\classes started by Arpit_Nanavati in C:\Codedelay\lazy-intialization-demo\lazy-intialization-demo) 2019-07-25 14:07:44.755 INFO 1816 - – [ main] c.c.l.LazyIntializationDemoApplication : No active profile set, falling back to default profiles: default 2019-07-25 14:07:46.166 INFO 1816 - – [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2019-07-25 14:07:46.178 INFO 1816 - – [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2019-07-25 14:07:46.178 INFO 1816 - – [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.21] 2019-07-25 14:07:46.317 INFO 1816 - – [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2019-07-25 14:07:46.318 INFO 1816 - – [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1504 ms LazyController init called 2019-07-25 14:07:46.553 INFO 1816 - – [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2019-07-25 14:07:46.734 INFO 1816 - – [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2019-07-25 14:07:46.740 INFO 1816 - – [ main] c.c.l.LazyIntializationDemoApplication : Started LazyIntializationDemoApplication in 2.482 seconds (JVM running for 2.932)
Now, you can see that only LazyService is not initialized now.