如何创建自定义注解替代@ConditionalOnProperty简化Spring Boot Bean加载控制?
自定义Spring Boot条件注解简化Bean加载控制
在Spring Boot项目中,原本通过@ConditionalOnProperty注解根据配置项myservice.implversion的值(如a、b)选择加载MyService接口的不同实现类,示例代码如下:
@ConditionalOnProperty( prefix = "myservice", name = "implversion", havingValue = "a" ) @Service public class MyServiceImplA implements MyService { // ... }
现在希望简化为更易用的自定义注解@OnMyServiceVersion,用法示例:
@OnMyServiceVersion(value = "a") @Service public class MyServiceImplA implements MyService { // ... }
之前遇到的问题
- 尝试用
@Conditional配合Condition接口,但不知道如何读取配置属性做检查 - Spring Boot内部的
OnPropertyCondition是非公开类,无法继承 - 尝试直接将
@ConditionalOnProperty作为元注解并引用当前注解的value()属性,这种写法无效:
// INVALID CODE, DO NOT USE @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @ConditionalOnProperty( prefix = "myservice", name = "implversion", havingValue = OnMyServiceVersion.value() ) public @interface OnMyServiceVersion { String value(); }
正确实现方案
步骤1:定义自定义注解
创建@OnMyServiceVersion注解,通过@Conditional指定自定义的条件判断类:
import org.springframework.context.annotation.Conditional; import java.lang.annotation.*; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Conditional(OnMyServiceVersionCondition.class) public @interface OnMyServiceVersion { String value(); }
步骤2:实现Condition判断类
编写OnMyServiceVersionCondition类,实现Condition接口,完成配置属性的读取与匹配逻辑:
import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; import org.springframework.core.env.Environment; import java.util.Map; public class OnMyServiceVersionCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { // 获取自定义注解的属性值 Map<String, Object> attributes = metadata.getAnnotationAttributes(OnMyServiceVersion.class.getName()); if (attributes == null) { return false; } String targetVersion = (String) attributes.get("value"); // 读取配置文件中的myservice.implversion配置 Environment environment = context.getEnvironment(); String currentVersion = environment.getProperty("myservice.implversion"); // 对比版本值,匹配则允许Bean加载 return targetVersion.equals(currentVersion); } }
完成以上两步后,即可通过@OnMyServiceVersion(value = "a")替代原有的@ConditionalOnProperty配置,实现完全一致的Bean加载控制效果。
内容的提问来源于stack exchange,提问作者AdrienW
相关产品推荐
相关产品推荐

