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

如何通过特性标志服务批量启用/禁用Spring Boot应用所有控制器?

一次性启用/禁用Spring Boot所有控制器的方案

针对你的需求,不用在每个控制器加判断,有两种实用方案,分别适合运行时动态开关和启动时静态开关的场景:

方案一:全局请求拦截器(运行时动态生效)

通过Spring MVC的HandlerInterceptor拦截所有请求,在请求到达控制器前检查特性标志,直接拦截禁用状态下的请求。

实现步骤:

  1. 编写全局拦截器类,注入你的特性标志服务,在preHandle方法中判断开关状态:
@Component
public class GlobalControllerToggleInterceptor implements HandlerInterceptor {

    private final FeatureFlagService featureFlagService;

    public GlobalControllerToggleInterceptor(FeatureFlagService featureFlagService) {
        this.featureFlagService = featureFlagService;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        boolean controllersEnabled = featureFlagService.isControllersEnabled();
        if (!controllersEnabled) {
            // 返回503服务不可用,可根据需求修改响应内容和状态码
            response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
            response.getWriter().write("Controllers are temporarily disabled");
            return false; // 终止请求流转,不会到达控制器
        }
        return true; // 放行请求到控制器
    }
}
  1. 注册拦截器,让它拦截所有路径(可按需排除健康检查、Actuator等特殊端点):
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    private final GlobalControllerToggleInterceptor toggleInterceptor;

    public WebMvcConfig(GlobalControllerToggleInterceptor toggleInterceptor) {
        this.toggleInterceptor = toggleInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(toggleInterceptor)
                .addPathPatterns("/**") // 拦截所有请求
                .excludePathPatterns("/actuator/health", "/actuator/info"); // 排除不需要拦截的路径
    }
}

这个方案的优势是运行时动态生效,修改特性标志后无需重启应用,立即生效。

方案二:@Conditional条件注解(启动时生效)

如果你的开关不需要运行时动态调整,仅在启动阶段决定是否启用控制器,可以用Spring的@Conditional注解实现。

实现步骤:

  1. 自定义条件判断类,读取特性标志的值:
public class ControllersEnabledCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 这里假设特性标志可通过环境变量获取,或直接注入你的FeatureFlagService(需通过ApplicationContext获取)
        Environment env = context.getEnvironment();
        return Boolean.parseBoolean(env.getProperty("feature.controllers.enabled", "true"));
    }
}
  1. 在启动类或控制器扫描配置上添加条件,仅当开关为true时才扫描并注册控制器:
@SpringBootApplication
@ComponentScan(
        basePackages = "com.yourpackage",
        includeFilters = @ComponentScan.Filter(
                type = FilterType.ANNOTATION,
                value = RestController.class
        ),
        useDefaultFilters = false
)
@Conditional(ControllersEnabledCondition.class)
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

或者给每个控制器类直接添加@Conditional(ControllersEnabledCondition.class),但批量扫描的方式更高效。

这个方案的特点是启动时一次性决定,开关状态在应用运行期间无法动态修改,适合不需要频繁变更的场景。

内容的提问来源于stack exchange,提问作者Đức Trường Đặng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 21:50:24