大数跨境
0
0

Spring Boot + OpenFeature 动态功能开关,支持各种复杂功能

Spring Boot + OpenFeature 动态功能开关,支持各种复杂功能 Spring全家桶实战案例
2025-12-18
0
导读:Spring Boot + OpenFeature 动态功能开关,支持各种复杂功能
Spring Boot 3实战案例锦集PDF电子书已更新至130篇!
🎉🎉《Spring Boot实战案例合集》目前已更新198个案例,我们将持续不断的更新。文末有电子书目录。

💪💪永久更新承诺

我们郑重承诺,所有订阅合集的粉丝都将享受永久免费的后续更新服务

💌💌如何获取
订阅我们的合集点我订阅,并通过私信联系我们,我们将第一时间将电子书发送给您。

→ 现在就订阅合集

环境:SpringBoot3.4.2



1. 简介

在项目开发里,由于不同业务场景的需求多变,新功能上线可能存在风险,且不同用户群体对功能需求有差异。功能开关能灵活控制功能启用与关闭,便于快速迭代、降低风险,还能实现功能的个性化投放,满足多样化业务需求。

在Spring Boot中,功能开关可通过@Profile按环境激活、@ConditionalOnProperty按属性配置控制等条件注解、@RefreshScope实现动态刷新配置。对于条件注解的更多内容请查看下面链接:

SpringBoot这些条件注解助你高效开发

而在本篇文章中我们将介绍一个非常不错的开源功能开关组件:OpenFeature。

什么是OpenFeature?

OpenFeature 提供了一个共享的、标准化的特性标志客户端——即一个软件开发工具包(SDK),该工具包可接入各种第三方特性标志提供商。无论你使用的是开源系统还是商业产品,无论它是自行托管还是云托管,OpenFeature 都为开发人员提供了一个一致、统一的 API,以便他们在应用程序中使用特性标志功能。

此图展现了,OpenFeature与"Flags-R-us"旗帜管理系统集成。

为实现这一目标,OpenFeature SDK 定义了若干灵活的抽象层

  • Evaluation API

Evaluation API是OpenFeature软件开发工具包(SDK)中与应用程序编写者交互的部分。它允许开发人员评估特性标志,并利用所得结果来影响控制流程或应用程序特性。评估API提供了一个框架,允许对行为进行定制,并与各种工具集成。

  • Evaluation Context

Evaluation Context是一个用于存储任意上下文数据的容器,这些数据可作为动态评估的基础。诸如主机或应用程序标识符等静态数据可进行全局配置。动态评估上下文(如Web应用程序中客户端的IP地址)可在标志评估期间隐式传播或显式传递,并且可以与静态值合并。

  • Providers

Provider是Evaluation API与所使用的标志管理系统之间的“转换层”。提供程序负责将提供给评估API的参数映射到关联标志管理系统中的等效表示形式。提供程序可能会封装供应商软件开发工具包(SDK)、调用定制的标志评估REST API,甚至解析某些本地存储的文件以解析标志值。

  • Hooks

钩子是一种机制,允许在标志评估生命周期的各个点添加任意行为。钩子让你能够扩展OpenFeature SDK,添加诸如验证已解析标志值、修改或向评估上下文添加数据、日志记录、遥测和跟踪等功能。

  • Events

事件使应用程序能够对提供程序或底层标志管理系统的状态变化做出反应。这些变化包括提供程序就绪状态、错误状态的变化,或者最有趣的是,标志配置的变化。

接下来,我们将基于Spring Boot详细的介绍OpenFeature的使用。

2.实战案例
2.1 引入依赖
<dependency>  <groupId>dev.openfeature</groupId>  <artifactId>sdk</artifactId>  <version>1.15.1</version></dependency><dependency>  <groupId>dev.openfeature.contrib.providers</groupId>  <artifactId>flagd</artifactId>  <version>0.11.10</version></dependency>
2.2 定义OpenFeatureAPI

OpenFeatureAPI 类是访问OpenFeature SDK的主要入口点。该类被设计为单例模式。如下示例:

@Configurationpublic class OpenFeatureConfig {  @Bean  OpenFeatureAPI openFeatureAPI() {    final OpenFeatureAPI openFeatureAPI = OpenFeatureAPI.getInstance();    return openFeatureAPI;  }}
接下来,我们就可以在需要的位置注入上面的 OpenFeatureAPI 进行功能标记的判断,如下示例:
@RestController@RequestMapping("/features")public class FeatureController {  private final OpenFeatureAPI openFeatureAPI ;  public FeatureController(OpenFeatureAPI openFeatureAPI) {    this.openFeatureAPI = openFeatureAPI;  }
  @GetMapping("/hello")  public String getHello() {    final Client client = openFeatureAPI.getClient();    // 判断功能标记 welcome-message 的状态    if (client.getBooleanValue("welcome-message"false)) {      return "您好,欢迎使用OpenFeature!";    }    return "Hello!";  }}
运行结果
当前环境中我们并没有对welcome-message进行任何的配置。
2.3 配置提供程序Provider

提供程序是 OpenFeature 中的重要概念,因为它们负责实际执行标志评估。正如上一步所示,未配置提供程序的 OpenFeature 始终返回默认值。若要实现真正的功能标志控制,我们需要注册一个提供程序。

如下示例,我们配置了一个基于内存的Provider:

@BeanOpenFeatureAPI openFeatureAPI() {  final OpenFeatureAPI openFeatureAPI = OpenFeatureAPI.getInstance();  Map<StringFlag<?>> flags = Map.of("welcome-message"Flag.builder()      .variant("on"true).variant("off"false)      .defaultVariant("on")      .build()) ;  openFeatureAPI.setProvider(new InMemoryProvider(flags )) ;  return openFeatureAPI;}
说明:如上配置了一个key为 welcome-message的flag,其中该flag具有on和off两种变体,分别返回true和flase;defaultVariant属性控制返回的变体,如上面配置为on,怎对应将返回true。
再次运行上面的接口,运行结果:
2.4 设置执行上下文 
我们可以通过当前执行的上下文信息进行功能的控制,修改配置如下:
@BeanOpenFeatureAPI openFeatureAPI() {  final OpenFeatureAPI openFeatureAPI = OpenFeatureAPI.getInstance();
  ContextEvaluator<Object> context = new ContextEvaluator<Object>() {    @Override    public Object evaluate(Flag flag, EvaluationContext evaluationContext) {      Value value = evaluationContext.getValue("region") ;      String region = flag.getFlagMetadata().getString("region") ;      return region.equals(value.asString()) ;    }  } ;   Map<StringFlag<?>> flags = Map.of("welcome-message"Flag.builder()      .flagMetadata(ImmutableMetadata.builder()          .addString("region""xj")          .build())      .contextEvaluator(context)      .build()) ;  openFeatureAPI.setProvider(new InMemoryProvider(flags)) ;  return openFeatureAPI;}
修改调用接口如下:
@GetMapping("/hello")public String getHello(String region) {  final Client client = openFeatureAPI.getClient();  EvaluationContext context = new MutableContext(Map.of("region"new Value(region)));  if (client.getBooleanValue("welcome-message"false, context)) {    return "您好,欢迎使用OpenFeature!";  }  return "Hello!";}
运行结果
2.5 使用flagd提供程序

flagd 是一款秉承 Unix 哲学的特性开关守护进程。可将其视为现成的、开源的、符合 OpenFeature 规范的特性开关后端系统。

安装
Window平台

https://github.com/open-feature/flagd/releases

从这里下载安装程序。通过如下方式启动:
./flagd start  --port 8013  --uri file:./app.flagd.json
Docker
# 下载镜像docker pull ghcr.io/open-feature/flagd:latest# 启动服务docker run -p 8013:8013 -v $(pwd)/:/etc/flagd/   -it ghcr.io/open-feature/flagd:latest start   --uri file:/etc/flagd/app.flagd.json
定义app.flagd.json配置文件
{  "flags": {    "welcome-message": {      "variants": {        "on": true,        "off": false      },      "state": "ENABLED",      "defaultVariant": "on"    }  }}
注,该配置文件中可以写各种复杂的规则。
修改配置类
@BeanOpenFeatureAPI openFeatureAPI() {  final OpenFeatureAPI openFeatureAPI = OpenFeatureAPI.getInstance();  openFeatureAPI.setProviderAndWait(new FlagdProvider()) ;  return openFeatureAPI;}
说明:默认情况下FlagdProvider连接的本地localhost:8013,我们可以通过环境变量或者带参数的FlagdProvider进行修改;环境遍历则通过:FLAGD_HOSTFLAGD_PORT分别进行设置主机和端口。
运行结果
在不重启服务的情况下,我们可以直接配置文件,会立即生效,我们将默认值改为off后,可以在flagd服务的控制台输出如下:
filepath event: ./app.flagd.json WRITE  {"component""sync""sync""fileinfo"}
再次访问


以上是本篇文章的全部内容,如对你有帮助帮忙点赞+转发+收藏
Java进阶:用这15个特性,1行顶100行基础代码

只会用map()和filter()?揭秘Java Stream 8大隐藏特性

自定义@Proxy注解!Spring Boot 动态控制代理功能,真的很强大

高级开发!Spring Boot 事务钩子终极方案:一个注解搞定

强大!Spring Boot 动态JSON字段按需输出,一个注解搞定

优雅!Spring Boot 一个注解,开启 SQL 数据动态权限控制

开发效率提升300%:Spring Boot + Temporal 用代码定义工作流

Spring Boot + JasperReport 一键生成PDF、HTML 与 XML 报表

Spring Boot 接口敏感字段脱敏的5大"王炸"方案

Spring Boot 通过@JsonComponent注解完全控制JSON数据

高级开发!Spring Boot 手写配置类动态刷新,多知识点综合应用

图片
图片
图片
图片
图片
图片
图片
图片
图片

【声明】内容源于网络
0
0
Spring全家桶实战案例
Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
内容 832
粉丝 0
Spring全家桶实战案例 Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
总阅读38
粉丝0
内容832