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.