必须掌握条件注解的扩展实现方法:先编写实现condition接口的类并重写matches方法,再定义@conditional引用该类或组合已有条件注解,最后在bean或配置类上应用,并通过启动参数、日志和注入验证生效。

要在Spring Boot中让某个Bean只在特定环境、类存在或配置开启时才注册进容器,必须掌握条件注解的扩展实现方法。这不只是套用现成注解,而是要能自定义判断逻辑、封装成可复用的注解,并精准控制Bean的加载时机。
编写自定义Condition实现类
第一步:创建一个实现org.springframework.context.annotation.Condition接口的类。
第二步:重写matches(ConditionContext context, AnnotatedTypeMetadata metadata)方法,在其中编写你的判断逻辑——比如检查系统属性、读取配置值、验证类路径是否存在某个类、甚至调用外部HTTP接口返回布尔结果。
第三步:注意context参数提供了完整上下文访问能力:【不能直接用ApplicationContext.getBean(),此时容器尚未刷新,只能通过context.getBeanFactory()获取已注册的早期Bean】;而metadata可用于解析注解上的属性值(如@MyConditional(value = "dev")中的value)。
定义自定义条件注解
方法一:使用@Conditional直接引用Condition类
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(MyServiceCondition.class)
public @interface ConditionalOnMyService { }
方法二:组合已有条件注解(推荐用于简单场景)
例如仅当配置项app.feature.enabled=true且类路径含RedisTemplate时生效:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ConditionalOnProperty(name = "app.feature.enabled", havingValue = "true")
@ConditionalOnClass(RedisTemplate.class)
public @interface EnableFeatureWithRedis { }
在Bean或配置类上应用自定义条件注解
第一步:将自定义注解加在@Component类上
@Component
@ConditionalOnMyService
public class MyFeatureService { ... }
第二步:或加在@Configuration类上,控制整组Bean的注册
@Configuration
@ConditionalOnMyService
public class MyFeatureAutoConfiguration { ... }
第三步:若该注解标注在@Bean方法上,需确保方法所在类本身已被Spring管理(如被@Component扫描到或显式@Import),否则注解不会触发。
验证条件是否生效
① 启动应用时添加JVM参数-Dspring.profiles.active=dev或修改application.yml启用对应配置。
② 在自定义Condition的matches()方法第一行插入System.out.println("MyServiceCondition triggered");,观察控制台是否打印。
③ 使用@Autowired注入目标Bean,如果启动时报No qualifying bean异常,说明条件未满足、Bean未注册;无异常且能正常调用,说明条件已生效。
这一步操作起来很简单,直接把文件拖进去就行。











