Java > Spring Framework > Spring Boot > Spring Boot Auto-Configuration
Conditional Bean Creation with Auto-Configuration
This example demonstrates how to use conditional annotations to control when a bean is created in an auto-configuration. We'll create a simple message sender bean that is only created if a specific property is set to true.
Message Sender Interface
This interface defines the contract for sending messages.
public interface MessageSender {
void sendMessage(String message);
}
Message Sender Implementation
This is a simple implementation of the MessageSender that logs the message.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DefaultMessageSender implements MessageSender {
private static final Logger logger = LoggerFactory.getLogger(DefaultMessageSender.class);
@Override
public void sendMessage(String message) {
logger.info("Sending message: {}", message);
}
}
Message Sender Auto-Configuration
This is the auto-configuration class. The @ConditionalOnProperty annotation ensures that the messageSender bean is only created if the property message.sender.enabled is set to true in the application properties or environment variables.
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MessageSenderAutoConfiguration {
@Bean
@ConditionalOnProperty(prefix = "message.sender", name = "enabled", havingValue = "true")
public MessageSender messageSender() {
return new DefaultMessageSender();
}
}
spring.factories File
Add the auto-configuration class to the spring.factories file to enable it.
# Auto-configuration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\n com.example.MessageSenderAutoConfiguration
Application Usage
In your application, inject the MessageSender. Note the use of required = false in the @Autowired annotation. This is because the bean may not be created if the property is not set. Check if the bean is null before using it.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class DemoApplication {
@Autowired(required = false)
private MessageSender messageSender;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public CommandLineRunner run() {
return args -> {
if (messageSender != null) {
messageSender.sendMessage("Hello, World!");
} else {
System.out.println("MessageSender is not enabled.");
}
};
}
}
Setting the Property
To enable the message sender, set the message.sender.enabled property to true in your application.properties or application.yml file.
# application.properties
message.sender.enabled=true
Concepts Behind the Snippet
The core concept revolves around Conditional Bean Creation using @ConditionalOnProperty. This allows developers to selectively instantiate beans based on the presence and value of configuration properties, making the application highly configurable and adaptable to different environments or deployments.
Real-Life Use Case
Consider a feature flag system. You might have a NewFeatureService that you only want to enable for a subset of users or during a beta testing phase. Using @ConditionalOnProperty, you can control whether this service is available based on a property like new.feature.enabled=true, allowing you to easily toggle the feature on or off without redeploying the application.
Best Practices
message.sender.enabled instead of just enabled).matchIfMissing attribute of @ConditionalOnProperty to determine the behavior when the property is not set.
Interview Tip
Be prepared to discuss the various conditional annotations available in Spring Boot (@ConditionalOnClass, @ConditionalOnBean, @ConditionalOnMissingBean, @ConditionalOnWebApplication, etc.) and how they can be used to create flexible and configurable applications.
When to Use Them
Use conditional bean creation when you need to control the creation of beans based on external factors, such as environment variables, system properties, or the presence of other beans. This is particularly useful for creating optional features or services.
Alternatives
Alternatives include using profiles or manually creating beans based on conditional logic in your configuration classes. However, conditional annotations provide a more declarative and maintainable approach.
Pros
Cons
FAQ
-
What happens if the property is not defined?
By default, if the property is not defined, the condition is not matched. However, you can use the `matchIfMissing` attribute to change this behavior. Setting `matchIfMissing = true` will cause the condition to be matched if the property is not defined. -
Can I use multiple conditional annotations on a single bean?
Yes, you can use multiple conditional annotations on a single bean. All conditions must be met for the bean to be created. -
How can I test conditional bean creation?
You can use Spring's testing framework to set properties and verify that the beans are created or not created as expected. You can override properties in your test configuration.