@ConditionalOnProperty 就是根据 配置文件(application.properties 或 yml)中的开关 来决定是否加载某个组件。它是实现“功能开关”最常用的手段。
1. 核心逻辑
简单来说,它的逻辑是:“去配置文件里看一眼,如果那个配置项的值符合我的预期,我就启动;否则,我就当不存在。”
2. 常用属性解析
3. 实战场景:切换支付网关
假设你的系统支持“支付宝”和“微信”两种支付方式,你想通过配置文件灵活切换。
代码实现
@Configuration
public class PayConfiguration {
@Bean
@ConditionalOnProperty(prefix = "pay", name = "type", havingValue = "alipay")
public PayService alipayService() {
return new AlipayServiceImpl();
}
@Bean
@ConditionalOnProperty(prefix = "pay", name = "type", havingValue = "wechat", matchIfMissing = true)
public PayService wechatService() {
return new WechatServiceImpl();
}
}
配置文件效果:
情况 A:
pay.type=alipay-> 加载alipayService。情况 B:
pay.type=wechat-> 加载wechatService。情况 C: 配置文件里什么都没写 -> 因为微信支付设置了
matchIfMissing = true,所以默认加载微信支付。
4. 进阶技巧:如何判断“开启”或“关闭”?
很多时候我们只是想做一个功能开关(True/False)。
@Bean
@ConditionalOnProperty(name = "feature.message-log.enabled", havingValue = "true")
public MessageLogger messageLogger() {
return new MessageLogger();
}
如果
havingValue没写,只要配置文件里该属性不为false,都会匹配成功。注意:如果你填了
havingValue = "true",那么配置文件里写enabled: true才能生效。
5. 常见坑点
拼写错误: 这是最常见的,IDE 通常不会对字符串里的配置名做强校验。建议配合
additional-spring-configuration-metadata.json使用以获得提示。松散绑定(Relaxed Binding): Spring 支持横杠、下划线、驼峰互转。例如
my.feature-enabled和my.featureEnabled在注解里通常都能匹配上,但建议保持风格统一。与
@Component连用: 它不仅能用在@Bean方法上,也可以直接顶在@Service或@Component类名上。
总结:两者的配合
在开发高级 Starter 时,通常会这样组合:
先用
@ConditionalOnProperty检查用户是否开启了该功能。再用
@ConditionalOnMissingBean检查用户是否自定义了实现。如果都满足,才加载默认的 Bean。
评论