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

Spring Boot集成FF4J:Web控制台渲染异常及特性开关不生效

FF4J集成Spring Boot 3.2.5问题解决

关于手动切换特性的策略

你要的仅通过Web控制台手动开关特性,属于静态开关策略(Static Flip Strategy)——直接通过修改Feature的enable属性控制特性状态,无需依赖动态判断逻辑。


问题1:Web控制台渲染异常

控制台渲染异常表现为页面样式错乱,如图所示:
控制台渲染异常截图

原因

依赖版本不匹配:ff4j-spring-boot-starter用的1.9版本,而ff4j-web用的2.0.0版本,版本差异导致前端静态资源(CSS/JS)加载异常,页面渲染错乱。

解决方法

统一FF4J相关依赖版本,建议全部使用2.0.0版本,同时ff4j-spring-boot-starter已包含ff4j-web,可以移除单独的ff4j-web依赖:

<!-- Feature toggling -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
  <version>3.2.5</version>
</dependency>
<dependency>
  <groupId>org.ff4j</groupId>
  <artifactId>ff4j-spring-boot-starter</artifactId>
  <version>2.0.0</version>
  <exclusions>
    <exclusion>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-ui</artifactId>
    </exclusion>
  </exclusions>
</dependency>

注:如果需要保留ff4j-web,必须保证其版本和ff4j-spring-boot-starter完全一致。


问题2:控制台切换特性无效果

原因

你给HELLO_EXAMPLE_FEATURE设置了ReleaseDateFlipStrategy,这个动态策略的优先级高于enable属性——FF4J会优先执行策略判断,忽略手动修改的enable状态,导致开关操作无效。

解决方法

移除动态策略,只保留静态开关:

@Bean
public FF4j ff4j(){
    FF4j ff4j = new FF4j();
    // 创建仅含静态开关的特性
    var feature = new Feature(HELLO_EXAMPLE_FEATURE);
    feature.setEnable(false);
    // 移除ReleaseDateFlipStrategy相关代码
    ff4j.createFeature(feature);
    return ff4j;
}

另外,默认的InMemoryFeatureStore是内存存储,修改后会实时生效,但重启应用会丢失配置。如果需要持久化配置,可以添加数据库依赖(如ff4j-store-jdbc)并配置数据源。


修正后的完整代码

配置类

package feature_toggle;

import org.ff4j.FF4j;
import org.ff4j.core.Feature;
import org.ff4j.web.FF4jDispatcherServlet;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Ff4jConfig {

    public static final String HELLO_EXAMPLE_FEATURE = "HELLO_EXAMPLE_FEATURE";

    @Bean
    public FF4j ff4j(){
        FF4j ff4j = new FF4j();
        var feature = new Feature(HELLO_EXAMPLE_FEATURE);
        feature.setEnable(false);
        ff4j.createFeature(feature);
        return ff4j;
    }

    @Bean
    @ConditionalOnMissingBean
    public FF4jDispatcherServlet ff4jDispatcherServlet(FF4j ff4j){
        FF4jDispatcherServlet ff4jDispatcherServlet = new FF4jDispatcherServlet();
        ff4jDispatcherServlet.setFf4j(ff4j);
        return ff4jDispatcherServlet;
    }

    @Bean
    public ServletRegistrationBean servletRegistrationBean(FF4jDispatcherServlet ff4jDispatcherServlet){
        return new ServletRegistrationBean(ff4jDispatcherServlet, "/ff4j-web-console/*");
    }
}

服务类

import org.ff4j.FF4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

@Service
public class FF4JService {

    @Resource
    private FF4j ff4j;

    public CommandLineRunner commandLineRunner(){
        return args -> {
            while(true){
                if(ff4j.check(Ff4jConfig.HELLO_EXAMPLE_FEATURE)){
                    System.out.println("Hello World!");
                } else {
                    System.out.println("Something went wrong!");
                }
                Thread.sleep(5000);
            }
        };
    }
}

注:将@Autowired替换为@Resource避免可能的依赖注入问题,同时移除了@Bean注解(CommandLineRunner无需单独注册为Bean,服务类中返回即可)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 07:27:05