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

Spring Boot自定义约束校验器重复注解报错,如何支持多Feature Flag?

解决重复注解编译错误的方法

出现“Duplicate annotation”编译错误的核心原因是:Java默认不允许同一注解在同一元素上重复使用,除非该注解被标记为@Repeatable,并搭配对应的容器注解。以下是具体解决步骤:

1. 创建容器注解

定义一个用来容纳多个BlockedWithoutEnabledFeatureFlag注解的容器注解,需满足JSR-380校验框架的规范要求:

@Constraint(validatedBy = {BlockedWithoutEnabledFeatureFlagsValidator.class})
@Target({FIELD, PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface BlockedWithoutEnabledFeatureFlags {
    // 用来存储多个重复的注解实例
    BlockedWithoutEnabledFeatureFlag[] value();
    
    // 必须包含校验注解的标准属性
    String message() default "{validation.constraints.BlockedWithoutEnabledFeatureFlags.message}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

2. 标记原注解为可重复注解

在原BlockedWithoutEnabledFeatureFlag注解上添加@Repeatable注解,指定对应的容器注解:

@Constraint(validatedBy = {BlockedWithoutEnabledFeatureFlagValidator.class})
@Target({FIELD, PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@ReportAsSingleViolation
@Repeatable(BlockedWithoutEnabledFeatureFlags.class) // 新增该行,标记为可重复注解
public @interface BlockedWithoutEnabledFeatureFlag {
    String message() default "{validation.constraints.BlockedWithoutEnabledFeatureFlag.message}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    FeatureFlag feature();
    String[] values() default {};
}

3. 实现容器注解的校验器

容器注解需要对应的校验器来处理多个注解实例的逻辑,这里可以复用原单个注解的校验逻辑,避免重复代码:

public class BlockedWithoutEnabledFeatureFlagsValidator implements ConstraintValidator<BlockedWithoutEnabledFeatureFlags, Object> {
    private final FeatureFlagService featureFlagService;
    private List<BlockedWithoutEnabledFeatureFlagValidator> validators = new ArrayList<>();

    // 通过构造函数注入依赖
    public BlockedWithoutEnabledFeatureFlagsValidator(FeatureFlagService featureFlagService) {
        this.featureFlagService = featureFlagService;
    }

    @Override
    public void initialize(BlockedWithoutEnabledFeatureFlags constraintAnnotation) {
        // 初始化每个单个注解的校验器实例
        for (BlockedWithoutEnabledFeatureFlag annotation : constraintAnnotation.value()) {
            BlockedWithoutEnabledFeatureFlagValidator validator = new BlockedWithoutEnabledFeatureFlagValidator(featureFlagService);
            validator.initialize(annotation);
            validators.add(validator);
        }
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        // 遍历所有校验器,只要有一个校验不通过则整体返回false
        for (BlockedWithoutEnabledFeatureFlagValidator validator : validators) {
            if (!validator.isValid(value, context)) {
                return false;
            }
        }
        return true;
    }
}

4. 正常使用重复注解

现在可以在字段上重复添加@BlockedWithoutEnabledFeatureFlag注解,编译不会再报错:

@JsonProperty(value = "name")
@BlockedWithoutEnabledFeatureFlag(feature = FeatureFlag.AAA, values = {"aaa", "bbb"})
@BlockedWithoutEnabledFeatureFlag(feature = FeatureFlag.BBB, values = {"ccc", "ddd"})
private String parameter;

内容的提问来源于stack exchange,提问作者Matexon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 04:12:11