
本文介绍了如何在 Spring Boot 应用中基于配置属性的值动态创建 Bean。通过使用 @ConditionalOnProperty 注解,可以根据指定的属性是否存在以及其值来决定是否创建某个 Bean,从而实现灵活的配置和 Bean 的动态加载。本文将提供详细的代码示例和使用说明,帮助开发者轻松掌握此技巧。
在 Spring Boot 应用开发中,经常会遇到需要根据配置文件的不同配置来选择性地创建 Bean 的场景。例如,根据某个开关属性的值来决定使用哪种类型的连接池,或者是否启用某个特定的功能模块。Spring Boot 提供了 @ConditionalOnProperty 注解,可以轻松实现这种动态 Bean 创建的需求。
@ConditionalOnProperty 注解
@ConditionalOnProperty 是 Spring Boot 提供的一个条件注解,用于根据指定的配置属性来决定是否创建 Bean。它允许你基于属性的存在与否,以及属性的值来控制 Bean 的注册。
@ConditionalOnProperty 注解的主要属性包括:
- prefix: 配置属性的前缀。
- name: 配置属性的名称。
- value: 配置属性期望的值。只有当属性的值与此值相等时,Bean 才会被创建。可以是一个字符串数组,表示多个允许的值。
- havingValue: 与 value 类似,但功能更强大,允许使用 SpEL 表达式。
- matchIfMissing: 如果指定的属性不存在,是否匹配。默认为 false,表示属性不存在时不匹配,Bean 不会被创建。设置为 true 时,属性不存在时匹配,Bean 会被创建。
使用示例
假设我们有两个 Bean,UserCredentialsConnectionFactoryAdapter 和 CachingConnectionFactory,我们希望根据配置属性 enable.userconnection 的值来决定创建哪个 Bean。如果 enable.userconnection 的值为 true,则创建 UserCredentialsConnectionFactoryAdapter Bean;如果为 false,则创建 CachingConnectionFactory Bean。
首先,定义两个 Bean:
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter;
@Configuration
public class ConnectionFactoryConfig {
@Bean
@ConditionalOnProperty(prefix = "enable", name = "userconnection", havingValue = "false", matchIfMissing = true)
public CachingConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
//connectionFactory.setTargetConnectionFactory(axonConnectionFactory); // 假设 axonConnectionFactory 已定义
connectionFactory.setReconnectOnException(true);
//connectionFactory.setSessionCacheSize(jmsSessionCacheSize); // 假设 jmsSessionCacheSize 已定义
return connectionFactory;
}
@Bean
@ConditionalOnProperty(prefix = "enable", name = "userconnection", havingValue = "true")
public UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter() throws Exception {
UserCredentialsConnectionFactoryAdapter connectionFactoryAdapter =
new UserCredentialsConnectionFactoryAdapter();
//connectionFactoryAdapter.setUsername(getUsername()); // 假设 getUsername() 已定义
//connectionFactoryAdapter.setPassword(getPassword()); // 假设 getPassword() 已定义
//connectionFactoryAdapter.setTargetConnectionFactory(messagingJMSService().getConnectionFactory(getName())); // 假设 messagingJMSService(), getName() 已定义
return connectionFactoryAdapter;
}
}在这个例子中,CachingConnectionFactory Bean 使用 @ConditionalOnProperty 注解,prefix 为 "enable",name 为 "userconnection",havingValue 为 "false"。matchIfMissing 设置为 true,意味着如果 enable.userconnection 属性不存在,则默认创建 CachingConnectionFactory Bean。
UserCredentialsConnectionFactoryAdapter Bean 也使用 @ConditionalOnProperty 注解,prefix 和 name 相同,havingValue 为 "true"。
接下来,可以在 application.properties 或 application.yml 文件中设置 enable.userconnection 属性的值。
如果 application.properties 文件包含以下内容:
enable.userconnection=true
则只会创建 UserCredentialsConnectionFactoryAdapter Bean。
如果 application.properties 文件包含以下内容:
enable.userconnection=false
则只会创建 CachingConnectionFactory Bean。
如果 application.properties 文件中没有定义 enable.userconnection 属性,由于 CachingConnectionFactory Bean 的 matchIfMissing 属性设置为 true,所以会默认创建 CachingConnectionFactory Bean。
注意事项
- 确保配置属性的名称和前缀正确无误,否则可能导致 Bean 无法按照预期创建。
- havingValue 属性的值是字符串类型,即使配置属性的值是布尔类型或数值类型,也需要使用字符串表示。
- matchIfMissing 属性需要根据实际需求进行设置。如果希望在属性不存在时默认创建 Bean,则设置为 true;否则设置为 false。
总结
@ConditionalOnProperty 注解是 Spring Boot 提供的一个强大的工具,可以方便地根据配置属性的值动态创建 Bean,从而实现灵活的配置和 Bean 的动态加载。通过合理使用 @ConditionalOnProperty 注解,可以使 Spring Boot 应用更加可配置和可扩展。










