Home » Java » Enterprise Java » Spring @Lazy Annotation

About Shubhra Srivastava

Shubhra Srivastava
Shubhra is a software professional and founder of ProgrammerGirl. She has a great experience with Java/J2EE technologies and frameworks. She loves the amalgam of programming and coffee :)

Spring @Lazy Annotation

Introduction:

The Spring framework, by default, loads and eagerly initializes all beans at the application startup itself. In our application, we might have some pretty resource-intensive beans. We’ll prefer to load such beans on a need basis. We can achieve this using the Spring @Lazy annotation.

In this tutorial, we’ll learn how to use @Lazy annotation to lazily load our beans.

Lazy Initialization:

If we mark our Spring configuration class with @Lazy annotation, then all defined beans with @Bean annotation will get lazily loaded:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
@Configuration
@ComponentScan(basePackages = "com.programmergirl.university")
@Lazy
public class AppConfig {
  
    @Bean
    public Student student() {
        return new Student();
    }
  
    @Bean
    public Teacher teacher() {
        return new Teacher();
    }
}

We can also lazy load just a single bean by using this annotation at the method level:

1
2
3
4
5
@Bean
@Lazy
public Teacher teacher() {
    return new Teacher();
}

Testing Lazy Loading:

Let’s quickly test out this functionality by running our application:

01
02
03
04
05
06
07
08
09
10
11
12
13
public class SampleApp {
    private static final Logger LOG = Logger.getLogger(SampleApp.class);
    public static void main(String args[]) {
        AnnotationConfigApplicationContext context =
          new AnnotationConfigApplicationContext(AppConfig.class);
         
        LOG.info("Application Context is already up");
  
        // Beans in our Config class lazily loaded
        Teacher teacherLazilyLoaded = context.getBean(Teacher.class);
        Student studentLazilyLoaded = context.getBean(Student.class);
    }
}

On our console, we’ll see:

1
2
3
4
5
6
Bean factory for ...AnnotationConfigApplicationContext:
...DefaultListableBeanFactory: [...]
...
Application Context is already up
Inside Teacher Constructor
Inside Student Constructor

Clearly, Spring initialized both Student and Teacher beans on demand and not while setting up the application context.

With @Autowired Annotation:

We can also use @Lazy annotation at an injection point: constructor, setter or field-level. 

Let’s say we have a Classroom class that we want to lazy-load:

1
2
3
4
5
6
7
8
@Component
@Lazy
public class Classroom {
    public Classroom() {
        System.out.println("Inside Classroom Constructor");
    }
    ...
}

And it’s wired to the University bean via @Autowired annotation:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
@Component
public class University {
  
    @Lazy
    @Autowired
    private Classroom classroom;
  
    public University() {
        System.out.println("Inside University Constructor");
    }
  
    public void useClassroomBean() {
        this.classroom.getDetails();
        ...
    }
}

Here, we have lazily-injected the Classroom bean. And so, while instantiating a University object, Spring will create and map a proxy Classroom object to it. Finally, when we invoke useClassroomBean(), only then it’ll create the actual Classroom instance:

1
2
3
4
5
6
7
8
9
// in our main() method
AnnotationConfigApplicationContext context
  = new AnnotationConfigApplicationContext();
  
LOG.info("Application Context is already up");
  
University university = context.getBean(University.class);
LOG.info("Time to use the actual classroom bean...");
university.useClassroomBean();

The above code will produce the following logs:

1
2
3
4
5
6
7
Bean factory for ...AnnotationConfigApplicationContext:
 ...DefaultListableBeanFactory: [...] ...
Inside University Constructor
...
Application Context is already up
Time to use the actual classroom bean...
Inside Classroom Constructor

As we can see, the instantiation of the Classroom object gets delayed until its actually needed.

Please note that, for lazy-injection, we must use @Lazy annotation on both the component class as well as the injection point.

Conclusion:

In this quick tutorial, we learned how to lazy load our Spring beans. We talked about lazy initialization and lazy injection.

Published on Java Code Geeks with permission by Shubhra Srivastava, partner at our JCG program. See the original article here: Spring @Lazy Annotation

Opinions expressed by Java Code Geeks contributors are their own.

(0 rating, 0 votes)
You need to be a registered member to rate this.
Start the discussion Views Tweet it!
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

Leave a Reply

avatar

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
Notify of