Using @Lazy annotation with @Bean and @Component example

In this post under Spring Core, I will explain with example the purpose of “@Lazy” annotation and how it reacts when used with “@Bean” and “@Component” annotation.

In Spring, we can use “@Lazy” annotation for two purposes
1) to instruct Spring framework to lazily create a singleton bean
2) to instruct Spring framework to lazily inject a singleton bean

In this post we will cover the first purpose.

By default when we run the Spring application, at the time of application context creation, the Spring framework creates an instances of all singleton beans.

By using “@Lazy” annotation with “@Bean” or “@Component” we are instructing Spring framework to postpone the creation of instance of a singleton bean until it is first accessed.

Lets see an example, we use below beans for our example

FileUploadService

package core.package48;

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

@Component
public class FileUploadService {
    public FileUploadService() {
        System.out.println("FileUploadService is created");
    }
}

FileDownloadService

package core.package48;

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

@Component
@Lazy
public class FileDownloadService {
    public FileDownloadService() {
        System.out.println("FileUploadService is created");
    }
}

We have two beans “FileUploadService” and “FileDownloadService” both annotated with “@Component” annotation but only “FileDownloadService” is annotated with “@Lazy” annotation.

FileSerializationService

package core.package48;

public class FileSerializationService {
    public FileSerializationService() {
        System.out.println("FileSerializationService is created");
    }
}

FileDeserializationService

package core.package48;

public class FileDeserializationService {
    public FileDeserializationService() {
        System.out.println("FileDeserializationService is created");
    }
}

I have created two more beans “FileSerializationService” and “FileDeserializationService”. I will create an instance of these classes using “@Bean” annotation in the below configuration class,
which is also the main class. I will configure “FileSerializationService” to lazily create.

Main class

package core.package48;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;
import org.springframework.scheduling.annotation.EnableAsync;

@Configuration
@ComponentScan(basePackages = "core.package48")
public class Example48 {

    @Bean
    @Lazy
    public FileSerializationService fileSerializationService() {
        return new FileSerializationService();
    }

    @Bean
    public FileDeserializationService fileDeserializationService() {
        return new FileDeserializationService();
    }

    public static void main(String[] args) throws InterruptedException {
        System.out.println("---------------------Application Context creation started-----------------------");
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Example48.class);
        System.out.println("---------------------Application Context creation ended-----------------------");
        System.out.println("---------------------Specifically requesting lazy beans-----------------------");
        FileDownloadService fileDownloadService = applicationContext.getBean(FileDownloadService.class);
        FileSerializationService fileSerializationService = applicationContext.getBean(FileSerializationService.class);
    }
}

When we run the above code, at the time of application context creation, an instance of “FileUploadService” and “FileDeserializationService” is created but creation of instance of “FileSerializationService”
and “FileDownloadService” is postponed or avoided.

After application context is created. We specifically request a bean for “FileSerializationService” and “FileDownloadService” using “getBean” method. At that time an instance of those beans are created.

Below is the output

Output

---------------------Application Context creation started-----------------------
FileUploadService is created
FileDeserializationService is created
---------------------Application Context creation ended-----------------------
---------------------Specifically requesting lazy beans-----------------------
FileDownloadService is created
FileSerializationService is created

In this way, Spring framework behaves when “@Lazy” annotation is used with “@Bean” and “@Component” annotation.

Leave a comment