Lazy Initialize @Autowired Dependencies with @Lazy

By default all autowired dependencies are eagerly created and configured at startup. When the @Lazy annotation is present together with the @Component annotation on class level, then the component will not be eagerly created by the container, but when the component is first requested. Together with the @Autowired injection point, you need to mark it with @Lazy annotation.

Lazy Initialize @Autowired Dependency

The Address bean is annotated with the @Lazy annotation, which makes this bean eligible for lazy initialization. This bean will be lazy loaded in the Person class which we’ll see next.

package com.memorynotfound.spring.core.lazy;

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

@Lazy
@Component
public class Address {

    public Address() {
        System.out.println("Address initialized");
    }

    @Override
    public String toString() {
        return "Address{}";
    }
}

The Person bean will be created eagerly. But the autowired Address bean is annotated with the @Lazy annotation, which tells the spring container to initialize the bean only when it’s first requested.

package com.memorynotfound.spring.core.lazy;

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

@Component
public class Person {

    private @Autowired @Lazy Address address;

    public Person() {
        System.out.println("Person initialized");
    }

    public Address getAddress() {
        return address;
    }
}

Spring Application Configuration

We’re working with annotations and components, so we need to enable component scanning and annotation configuration. So we need to enable these features and we can do this by adding the <component-scan/> element.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.memorynotfound"/>

</beans>

Running The Application

This application will print appropriate messages to the console, indicating what bean is loading and when.

package com.memorynotfound.spring.core.lazy;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Run {

    public static void main(String... args) throws InterruptedException {
        ApplicationContext context = new ClassPathXmlApplicationContext("app-config.xml");
        System.out.println("Application context loaded");
        System.out.println("Getting Person Bean");
        Person person = context.getBean(Person.class);

        System.out.println("Waiting...");
        Thread.sleep(1000);

        System.out.println("Getting the address");
        Address address = person.getAddress();
        System.out.println(address + ".toString()");
    }
}

Output

This output is generated with lazy-initialization enabled.

Person initialized
Application context loaded
Getting Person Bean
Waiting...
Getting the address
Address initialized
Address{}.toString()

This output is generated with lazy-initialization disabled

Address initialized
Person initialized
Application context loaded
Getting Person Bean
Waiting...
Getting the address
Address{}.toString()

References

Download

You may also like...