Home Spring Framework Using Spring @Lazy annotation

Using Spring @Lazy annotation

In this guide we will learn about how to initialize beans lazily using Spring @Lazy annotation. We also look at XML configuration for lazy initialization.

1. Spring Lazy Initialization

The Spring framework, by default, initializes all singleton beans eagerly at the application startup and put them in application context. However, in some cases we need to create beans whenever they required, but not at the application startup or bootstrapping application context time. In Spring, we can achieve this by using @Lazy annotation.

Since Spring 3.0, @Lazy annotation available, which indicates whether a bean is to be lazily initialized. We can use @Lazy annotation in several ways.

1.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 3 beans and Customer bean marked with @Lazy.

@Configuration
@ComponentScan("com.javabydeveloper.spring.lazy")
public class AppConfigForLazy {

    @Bean
    public Company companyBean(){
        return new Company();
    }

    @Bean
    public Employee employeeBean(){
        return new Employee();
    }
    
    @Lazy
    @Bean
    public Customer customerBean(){
        return new Customer();
    }
}

Let’s test the configuration.

public class ApplicationLazyConfigDemo {

	public static void main(String[] args) {
		ApplicationContext ctxt = new AnnotationConfigApplicationContext(AppConfigForLazy.class);

		//Customer customer = ctxt.getBean(Customer.class);
	}
}

Notice the results in console, customerBean not initialized on startup.

Creating shared instance of singleton bean 'appConfigForLazy'
Creating shared instance of singleton bean 'companyBean'
Creating shared instance of singleton bean 'employeeBean'

Uncomment line Customer customer = ctxt.getBean(Customer.class); in ApplicationLazyConfigDemo and run again, this time you will notice customerBean is created. Means, Spring creates instance whenever it requires for the @Lazy annotated beans.

Creating shared instance of singleton bean 'appConfigForLazy'
Creating shared instance of singleton bean 'companyBean'
Creating shared instance of singleton bean 'employeeBean'
Creating shared instance of singleton bean 'customerBean'

1.2. Using @Lazy on @Configuration class

If Lazy is present on a @Configuration class, this indicates that all @Bean methods within that @Configuration should be lazily initialized. Lets change above configuration class, place the @Lazy annotation at class level.

@Lazy
@Configuration
@ComponentScan("com.javabydeveloper.spring.lazy")
public class AppConfigForLazy {

    @Bean
    public Company companyBean(){
        return new Company();
    }

    @Bean
    public Employee employeeBean(){
        return new Employee();
    }
    
    @Bean
    public Customer customerBean(){
        return new Customer();
    }
}

Testing:

public class ApplicationLazyConfigDemo {

	public static void main(String[] args) {
		ApplicationContext ctxt = new AnnotationConfigApplicationContext(AppConfigForLazy.class);

		Customer customer = ctxt.getBean(Customer.class);
	}
}

Results:

As we requested customerBean, Spring initialized only customerBean.

Creating shared instance of singleton bean 'appConfigForLazy'
Creating shared instance of singleton bean 'customerBean'

1.3. Eager Initialization using @Lazy(value = false)

If we place @Lazy at @Configuration class, all the @Bean methods within that class should be initialized lazy. To override this for specific bean, you can use @Lazy(value = false) for eager initialization.

@Lazy
@Configuration
@ComponentScan("com.javabydeveloper.spring.lazy")
public class AppConfigForLazy {

   @Bean
    public Company companyBean(){
        return new Company();
    }

    @Bean
    public Employee employeeBean(){
        return new Employee();
    }
    
    @Lazy(value = false)
    @Bean
    public Customer customerBean(){
        return new Customer();
    }
}

1.4. @Lazy with @Autowired

@Lazy can be places on Spring @Autowired injection points. We can use with Setter Injection or Constructor Injection or Field Injection.

Let’s see an example. Here the student bean marked with @Lazy for lazy loading of bean. Make sure you need to mark @Lazy on both class and on where it referencing to.

@Component
public class User {
	
	@Lazy
	@Autowired
	private Student student;

	public User() {
	   System.out.println("User Instance Created");
	}

	public Student getStudent() {
		return student;
	}
}
@Lazy
@Component
public class Student {

	public Student() {
		System.out.println("Student Instance Created");
	}
	
	private String name;

	public String getName() {
		return name;
	}
}

Testing:

public class ApplicationLazyConfigDemo {

	public static void main(String[] args) {
		ApplicationContext ctxt = new AnnotationConfigApplicationContext(AppConfigForLazy.class);

		Customer customer = ctxt.getBean(Customer.class);
		
		User user = ctxt.getBean(User.class);
		System.out.println(user.getStudent().getName());
	}
}

Results:

student instance will be created when ever it access using user.getStudent().

2. Lazy initialization using XML

If you are using XML configuration for bean definitions, you can apply lazy initialization to the beans either globally to all beans or to a specific bean.

2.1. To mark a specific bean for lazy initialization in XML, you need to add lazy-init=”true” to the bean definition.

lazy-beans-context.xml:

Following XML definitions person bean marked with lazy-init=”true”.

<?xml version="1.0" encoding="UTF-8"?>
<beans>
	<bean id="person" class="com.javabydeveloper.spring.lazy.Person"
		lazy-init="true">
	</bean>

	<bean id="department"
		class="com.javabydeveloper.spring.lazy.Department">
	</bean>

</beans>

Let’s load the beans in lazy-beans-context.xml to the application context using Spring @ImportResource.

@Configuration
@ImportResource("classpath:lazy-beans-context.xml")
public class AppConfigForLazyXmlConfig {

}

Testing:

public class ApplicationLazyXmlConfigDemo {

	public static void main(String[] args) {
		ApplicationContext ctxt = new AnnotationConfigApplicationContext(AppConfigForLazyXmlConfig.class);

		//Person person = ctxt.getBean(Person.class);	
	}
}

Results:

You can notice that person bean not loaded eagerly.

Creating shared instance of singleton bean 'appConfigForLazyXmlConfig'
Creating shared instance of singleton bean 'department'

Uncomment line Person person = ctxt.getBean(Person.class);, run again, person bean will be initialized on demand, you will get following results.

Creating shared instance of singleton bean 'appConfigForLazyXmlConfig'
Creating shared instance of singleton bean 'department'
Creating shared instance of singleton bean 'person'

2.2. To initialize all the beans defined in XML lazily, use default-lazy-init=”true” to the beans root tag.

<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="true">
	<bean id="person" class="com.javabydeveloper.spring.lazy.Person">
	</bean>

	<bean id="department"
		class="com.javabydeveloper.spring.lazy.Department">
	</bean>

</beans>

2.3. When you use default-lazy-init=”true” , all the beans marked for lazy initialization. We can override this using lazy-init=”false” to make specific bean for eager loading.

<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="true">
	<bean id="person" class="com.javabydeveloper.spring.lazy.Person"
		lazy-init="false">
	</bean>

	<bean id="department"
		class="com.javabydeveloper.spring.lazy.Department">
	</bean>

</beans>

3. Conclusion

In this guide we discussed on how to initialize beans lazily using Spring @Lazy annotation. We also looked at XML configuration for lazy initialization.

9. References

  1. Spring Reference Document
  2. Spring Java Document

Other Related Tutorials:

  1. Spring @Autowired
  2. Spring @ComponentScan Filter Types
  3. Spring Boot XML Configuration
  4. Spring Injecting Collection
  5. Spring @Order
  6. Spring @Primary
  7. Spring @Import
  8. Spring @ComponentScan

LEAVE A REPLY

Please enter your comment!
Please enter your name here