Spring @Lazy Annotation Example

In this section we will learn about @Lazy Annotation.


By default, the Spring IoC container creates and initializes all singleton beans at time of application startup. This default behavior ensures that any possible error caught immediately. This feature is really good to avoid any runtime errors but there are a number of use cases when we do not want Spring IoC to create beans on startup but create it when requested by the application. We can prevent this pre-initialization of a singleton bean by using the @Lazy annotation.

The @Lazy annotation may be used on any class annotated with @Component, @Service & @Repository or on methods annotated with @Bean.

1. Using @Lazy on @Bean method

If @Lazy annotation present on a @Bean method, Spring initializes that specific bean lazily. Let’s have a look at example. In following example, we have configured 2 beans and SMSService bean marked with @Lazy.

public class EmailService {

public EmailService() {
System.out.println("Inside EmailService Constuctor");
}
}


public class SMSService {

public SMSService() {
System.out.println("Inside SMSService Constuctor");
}
}


@Configuration
public class AppConfig {

@Lazy
@Bean
public SMSService smsService() {
return new SMSService();
}

@Bean
public EmailService emailService() {
return new EmailService();
}
}
Let’s test the configuration.

@SpringBootApplication
public class Application {

public static void main(String[] args) {

ConfigurableApplicationContext context =
SpringApplication.run(Application.class, args);

//SMSService smsService = context.getBean(SMSService.class);

context.close();
}
}

Console Output:
Inside EmailService Constuctor 
Notice the results in console, smsService bean not initialized on startup.
Uncomment line SMSService smsService = context.getBean(SMSService.class); and run again, this time you will notice smsService bean is created. Means, Spring creates instance whenever it requires for the @Lazy annotated beans.

@SpringBootApplication
public class Application {

public static void main(String[] args) {

ConfigurableApplicationContext context =
SpringApplication.run(Application.class, args);

SMSService smsService = context.getBean(SMSService.class);

context.close();
}
}

Console Output:
Inside EmailService Constuctor
Inside SMSService Constuctor
This time you will notice smsService bean is created. Means, Spring creates instance whenever it requires for the @Lazy annotated beans.

2. Using @Lazy on @Service class

If @Lazy annotation present on a @Service class, Spring initializes that specific bean lazily. Let’s have a look at example. In following example, we have configured 2 beans and CartService bean marked with @Lazy.

@Service
public class ShoppingService {

public ShoppingService() {
System.out.println("Inside ShoppingService Constuctor");
}
}


@Lazy
@Service
public class CartService {

public CartService() {
System.out.println("Inside CartService Constuctor");
}
}
Let’s test,

@SpringBootApplication
public class Application {

public static void main(String[] args) {

ConfigurableApplicationContext context =
SpringApplication.run(Application.class, args);

//CartService cartService = context.getBean(CartService.class);

context.close();
}
}

Console Output:
Inside ShoppingService Constuctor

Uncomment line CartService cartService = context.getBean(CartService.class); and run again, this time you will notice cartService bean is created. Means, Spring creates instance whenever it requires for the @Lazy annotated beans.

@SpringBootApplication
public class Application {

public static void main(String[] args) {

ConfigurableApplicationContext context =
SpringApplication.run(Application.class, args);

CartService cartService = context.getBean(CartService.class);

context.close();
}
}

Console Output:
Inside ShoppingService Constuctor
Inside CartService Constuctor
This time you will notice cartService bean is created. Means, Spring creates instance whenever it requires for the @Lazy annotated beans.

The following example creates a Spring Boot application which uses @Lazy annotation.

Project Directory



pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.knf.dev.demo</groupId>
<artifactId>spring-lazy-annotation-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-lazy-annotation-example</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

EmailService.java

package com.knf.dev.demo.service;

public class EmailService {

public EmailService() {
System.out.println("Inside EmailService Constuctor");
}
}

SMSService.java

package com.knf.dev.demo.service;

public class SMSService {

public SMSService() {
System.out.println("Inside SMSService Constuctor");
}
}

AppConfig.java

package com.knf.dev.demo.config;

import com.knf.dev.demo.service.EmailService;
import com.knf.dev.demo.service.SMSService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

@Configuration
public class AppConfig {

@Lazy
@Bean
public SMSService smsService() {
return new SMSService();
}

@Bean
public EmailService emailService() {
return new EmailService();
}
}

ShoppingService.java

package com.knf.dev.demo.service;

import org.springframework.stereotype.Service;

@Service
public class ShoppingService {

public ShoppingService() {
System.out.println("Inside ShoppingService Constuctor");
}
}

CartService.java

package com.knf.dev.demo.service;

import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

@Lazy
@Service
public class CartService {

public CartService() {
System.out.println("Inside CartService Constuctor");
}
}

Run the application - Application.java

package com.knf.dev.demo;

import com.knf.dev.demo.service.CartService;
import com.knf.dev.demo.service.SMSService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class Application {

public static void main(String[] args) {

ConfigurableApplicationContext context =
SpringApplication.run(Application.class, args);

SMSService smsService = context.getBean(SMSService.class);
CartService cartService = context.getBean(CartService.class);

context.close();
}
}

Application is the entry point that sets up the Spring Boot application. The @SpringBootApplication annotation enables auto-configuration and component scanning. 

Let's run this Spring boot application from either IntelliJ IDEA IDE by right click - Run 'Application.main()'
Or you can use the below maven command to run:

mvn spring-boot:run

Console Output:
Inside ShoppingService Constuctor
Inside EmailService Constuctor
Inside SMSService Constuctor
Inside CartService Constuctor


Download Source Code

More related topics,

Spring Web Annotations


Spring Core Annotations

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete