必须自定义条件注解并显式绑定@conditional(featurecondition.class),否则注解失效;featurecondition通过metadata.getannotationattributes()获取属性并校验application.yml中feature.payment.enabled配置值来决定bean是否注入。

要在SpringBoot中让某个配置类或Bean只在特定环境、依赖存在或配置开启时才生效,必须自定义条件注解——它不是简单加个@Target和@Retention就能用的,核心在于绑定Condition实现类并正确触发判断逻辑。
定义条件注解接口
新建注解类ConditionalOnFeature,限定作用范围为类和方法,生命周期保留至运行时:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(FeatureCondition.class)
public @interface ConditionalOnFeature {
String value() default "";
}
【必须显式指定@Conditional(FeatureCondition.class)】 这一步缺失会导致注解完全失效,Spring不会自动关联任何条件逻辑。
编写Condition实现类
创建FeatureCondition类,实现Spring的Condition接口:
public class FeatureCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String featureName = getFeatureName(metadata);
if ("payment".equals(featureName)) {
// 检查application.yml是否启用payment功能
return "true".equalsIgnoreCase(context.getEnvironment().getProperty("feature.payment.enabled"));
}
return false;
}
private String getFeatureName(AnnotatedTypeMetadata metadata) {
Map
return attrs != null ? (String) attrs.get("value") : "";
}
}
这一步的关键是:metadata.getAnnotationAttributes()必须传入完整类名字符串,写错包路径或大小写会返回null,导致featureName为空字符串,条件永远不满足。
在配置类上使用该注解
方法一:直接标注@Configuration类
@Configuration
@ConditionalOnFeature("payment")
public class PaymentAutoConfiguration {
@Bean
public PaymentService paymentService() {
return new DefaultPaymentService();
}
}
方法二:标注@Bean方法(更灵活)
@Configuration
public class FeatureConfig {
@Bean
@ConditionalOnFeature("sms")
public SmsSender smsSender() {
return new AliyunSmsSender();
}
}
验证条件是否生效
第一步:在application.yml中添加配置项
feature:
payment:
enabled: true
第二步:启动应用后检查日志,确认PaymentAutoConfiguration类被加载;
第三步:将enabled改为false → 重启 → 观察PaymentService Bean不再注入容器,且日志中无该配置类加载记录。
这一步操作起来很简单,直接把文件拖进去就行。但若跳过第二步验证,仅靠代码编译通过就认为注解已生效,极易掩盖Condition逻辑未触发的问题。











