You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建自定义注解替代@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 17:25:51