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.
