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

Spring中能否自定义扩展@ConditionalOn系列注解实现条件配置复用

Spring自定义功能开关注解实现方案

完全可以通过Spring的组合注解特性封装自定义条件注解,避免重复编写@ConditionalOnExpression表达式,同时满足DRY原则和编译时检查的要求。


1. 封装自定义条件注解

如果你的条件逻辑可以用简单的SpEL表达式实现,可以直接复用@ConditionalOnExpression封装自定义注解:

import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import java.lang.annotation.*;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
// 填入你之前重复使用的条件表达式,示例为配置项app.feature.rest-enabled为true时生效,默认关闭
@ConditionalOnExpression("${app.feature.rest-enabled:false}")
public @interface ConditionalOnRest {
}

按照相同方式可以快速定义其他功能的条件注解:

  • @ConditionalOnRestAdmin:对应REST管理后台功能
  • @ConditionalOnIndex:对应索引处理功能
  • @ConditionalOnArchive:对应归档处理功能
  • @ConditionalOnQueueProcessing:对应队列消费功能

2. 业务组件上直接使用自定义注解

替换之前每个组件上重复编写的@ConditionalOnExpression注解,直接使用自定义注解即可:

示例REST接口控制器:

@RestController
@ConditionalOnRest
public class BusinessRestController {
    // 接口实现逻辑
}

示例队列消费组件:

@Component
@ConditionalOnQueueProcessing
public class OrderQueueConsumer {
    // 队列消费逻辑
}

3. 不同部署节点配置开关

部署时仅需要在对应节点的配置文件中开启需要的功能开关即可,不需要的功能对应的Bean不会被Spring初始化,不会占用资源、启动多余线程:

  • REST服务节点配置:app.feature.rest-enabled=true
  • 管理后台节点配置:app.feature.rest-admin-enabled=true
  • 索引处理节点配置:app.feature.index-enabled=true
  • 归档处理节点配置:app.feature.archive-enabled=true
  • 队列消费节点配置:app.feature.queue-processing-enabled=true

进阶优化:完全自定义Condition实现

如果你的条件逻辑比较复杂,不想使用SpEL表达式,还可以通过自定义Spring Condition实现类的方式封装,完全避免SpEL写错的风险,支持编译时检查:

// 自定义条件逻辑实现类
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class RestFeatureCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 可在此实现任意复杂的判断逻辑,比如多配置项组合判断、环境校验等
        return context.getEnvironment()
                .getProperty("app.feature.rest-enabled", Boolean.class, false);
    }
}

对应的自定义注解:

import org.springframework.context.annotation.Conditional;
import java.lang.annotation.*;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(RestFeatureCondition.class)
public @interface ConditionalOnRest {
}

这种方式的条件逻辑完全由Java代码实现,IDE可以做语法检查,完全避免拼写错误,更适合复杂的多特性开关场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 16:45:03