Using @Lazy annotation with @Autowired annotation example

In this post under Spring Core, I will show with example how to use “@Lazy” annotation with “@Autowired” annotation and how it change the behavior of Spring framework.

In previous post, I showed with example how to use “@Lazy” annotation with “@Component” and “@Bean” annotation and how they change the behavior of Spring framework.

Just for recap, when we use “@Lazy” annotation with “@Component” and “@Bean”, we are basically telling Spring framework to delay the instance creation of the bean until it is actually requested. As a
result Spring framework will not create an instance of bean at the time of application context creation.

Now when we use “@Lazy” annotation with “@Autowired” annotation, we are basically telling Spring framework to delay the injection of requested bean into the container bean. So basically we are telling
Spring framework to create an instance of bean at the time of application context creation but don’t inject into the container bean until it is first requested.

Lets say we have container bean “A” and contained bean “B”. We call “A” container bean as it contains the bean “B” and we call “B” as contained bean because it is contained by bean “A”.

Lets also say we have a method “displayB” in contained bean “B” and we have method “displayA” in container bean “A”. “displayB” method is called by “displayA” method.

Now when the application runs, Spring framework creates an instance of both “A” and “B” but doesn’t inject “B” into “A” instead inject a proxy of “B”.

Now when the container bean “A”‘s “displayA” method is called which in turn calls “displayB”. At that time previously created actual contained bean “B” replaces the proxy and calls the “displayB” method.

Lets see an example.

For our example we will create “FileUploadService” class

FileUploadService

package core.package49;

import org.springframework.stereotype.Component;

@Component
public class FileUploadService {
    public FileUploadService() throws InterruptedException {
        System.out.println("FileUploadService constructor");
    }

    public void upload() {
        System.out.println("upload method is called");
    }
}

Next we will create “FileManager” class to which “FileUploadService” is injected lazily

FileManager

package core.package49;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

@Component
public class FileManager {
    @Autowired
    @Lazy
    private FileUploadService fileUploadService;

    public FileManager() {
        System.out.println("FileManager constructor");
    }

    public void upload() {
        fileUploadService.upload();
    }
}

As you can see in the above code, when adding “@Autowired” annotation to the instance variable of type “FileUploadService”, we are also adding “@Lazy” annotation.

So we are telling Spring framework to inject the bean “FileUploadService” only when it is first accessed.

Below is the main class for your reference

Main class

package core.package49;

import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

@Configuration
@ComponentScan(basePackages = "core.package49")
public class Example49 {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(Example49.class);
        FileManager fileManager = context.getBean(FileManager.class);
        fileManager.upload();
    }
}

In this way “@Lazy” annotation works when used with “@Autowired” annotation.

Leave a comment