How do I implement lazy initialization and conditional bean loading?

To implement lazy initialization and conditional bean loading in a Spring Boot application, you can make use of several Spring features. Here’s a breakdown of both concepts:

Lazy Initialization

Lazy initialization ensures that a Spring bean is not loaded into the application context until it is explicitly required. This can help to optimize startup time and resource usage.

1. Enable Lazy Initialization for All Beans

You can set the default behavior to lazily initialize all beans in your application by setting this property in the file: application.properties

spring.main.lazy-initialization=true

This affects all Spring beans.

2. Mark a Specific Bean as Lazy

If you want to lazily initialize only some beans, you can use the @Lazy annotation on a bean or class:

package org.kodejava.spring;

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

@Component
@Lazy
public class LazyBean {
    public LazyBean() {
        System.out.println("LazyBean loaded!");
    }

    public void performAction() {
        System.out.println("Action performed!");
    }
}

Here, the LazyBean class will only be initialized when it is first accessed via @Autowired or explicitly instantiated from the application context.

3. Lazy Initialization in Configuration Classes

If you’re defining beans via a @Configuration class, you can also use @Lazy:

package org.kodejava.spring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

@Configuration
public class AppConfig {

    @Bean
    @Lazy
    public String myLazyBean() {
        System.out.println("Lazy bean created!");
        return "I am lazy";
    }
}

Conditional Bean Loading

Conditional bean loading allows certain beans to be loaded into the application context only if certain conditions are met.

1. Using @ConditionalOnProperty

You can conditionally load a bean based on a property in the application configuration file:

package org.kodejava.spring;

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ConditionalConfig {

    @Bean
    @ConditionalOnProperty(name = "feature.enabled", havingValue = "true", matchIfMissing = false)
    public String conditionalBean() {
        System.out.println("Conditional Bean created!");
        return "Conditional Bean";
    }
}

In this example, the bean is created only if feature.enabled=true is specified in application.properties.

feature.enabled=true

2. Using @Conditional Custom Conditions

You can implement custom conditions using the @Conditional annotation and your own condition class:

package org.kodejava.spring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Conditional;

@Configuration
public class CustomConditionalConfig {

    @Bean
    @Conditional(MyCustomCondition.class)
    public String customConditionalBean() {
        System.out.println("Custom Conditional Bean created!");
        return "Custom Conditional Bean";
    }
}

The condition class must implement Condition:

package org.kodejava.spring;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class MyCustomCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // Example: Define your own condition here
        String property = context.getEnvironment().getProperty("custom.condition");
        return "true".equals(property);
    }
}

Add the property in application.properties:

custom.condition=true

3. Using @Profile for Environment-Specific Beans

You can load a bean conditionally based on the active Spring profile by using the @Profile annotation:

package org.kodejava.spring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Configuration
public class ProfileBasedConfig {

    @Bean
    @Profile("dev")
    public String devBean() {
        System.out.println("Dev Bean created!");
        return "Dev Bean";
    }

    @Bean
    @Profile("prod")
    public String prodBean() {
        System.out.println("Prod Bean created!");
        return "Prod Bean";
    }
}

Set the active profile in application.properties:

spring.profiles.active=dev

Combining Lazy and Conditional Loading

You can use both lazy initialization and conditional loading together. For example:

package org.kodejava.spring;

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

@Configuration
public class CombinedConfig {

    @Bean
    @Lazy
    @ConditionalOnProperty(name = "lazy.conditional.enabled", havingValue = "true")
    public String lazyConditionalBean() {
        System.out.println("Lazy and Conditional Bean created!");
        return "Lazy and Conditional Bean";
    }
}

Set a property in application.properties:

lazy.conditional.enabled=true

By using these techniques, you can effectively manage lazy initialization and conditional bean loading in your Spring application.

Leave a Reply

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