文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

灵活控制!结合 Spring Boot 3.3 的 API 基于 Togglz 的特性开关和前端 UI 实现特性开关的管理

2024-11-29 18:33

关注

传统上,功能的控制往往通过条件语句或分支管理来实现,而特性开关为这一过程提供了更为灵活且细粒度的控制方式。通过引入 Togglz 框架,Spring Boot 应用可以轻松管理特性开关的启用、禁用以及其背后的配置。在本篇文章中,我们将深入探讨如何基于 Togglz 框架,结合 Spring Boot3.3 的 API 和前端 UI 实现特性开关的管理,并使用 MySQL 数据库存储开关状态。

Togglz 框架及其特性

Togglz 是一个用于管理特性开关的轻量级框架,它提供了灵活的 API 和丰富的扩展性,能够帮助开发者在应用程序中快速集成特性开关管理功能。它的主要功能包括:

  1. 简单的特性开关管理:通过注解和配置,可以快速定义和管理特性开关。
  2. 多种持久化方式:Togglz 支持将特性开关的状态存储在内存、文件系统或数据库中。
  3. 支持 Web UI 管理:提供默认的 Web UI,用于在生产环境中实时管理特性开关。
  4. 集成多种条件控制:通过条件表达式和用户分组,可以针对不同用户或环境启用或禁用特性。

项目网址:https://github.com/togglz/togglz

运行效果:

图片

若想获取项目完整代码以及其他文章的项目源码,且在代码编写时遇到问题需要咨询交流,欢迎加入下方的知识星球。

本文将基于 Togglz 框架,结合 API 调用实现特性开关的动态管理,并在前端页面通过 AJAX 调用实现特性状态的动态获取与更新。

项目依赖配置

Maven pom.xml 配置



	4.0.0
	
		org.springframework.boot
		spring-boot-starter-parent
		3.3.3
		 
	
	com.icoderoad
	togglz-flag
	0.0.1-SNAPSHOT
	togglz-flag
	Demo project for Spring Boot
	
	
		17
		4.4.0
	
	
		
	    
	        org.springframework.boot
	        spring-boot-starter
	    
	
	    
	    
		    org.togglz
		    togglz-spring-boot-starter
		    ${togglz.version}
		
		
		
	    
	        org.springframework.boot
	        spring-boot-starter-data-jpa
	    

		
		
		
			com.mysql
			mysql-connector-j
			runtime
		
	    
	    
	    
	        org.springframework.boot
	        spring-boot-starter-web
	    
	    
	    
			org.projectlombok
			lombok
			true
		
	
	    
	    
	        org.springframework.boot
	        spring-boot-starter-thymeleaf
	    

		
			org.springframework.boot
			spring-boot-starter-test
			test
		
	

	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
		
	

application.yaml 配置

server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/togglz_db
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

后端实现

大家可以通过创建一个实现 TogglzConfig 接口的配置类来定义 FeatureManager 的配置。例如,可以配置它使用 InMemoryStateRepository 或 JDBCStateRepository 来存储特性开关的状态。

正确的 Togglz 配置示例

package com.icoderoad.togglzflag.config;

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.togglz.core.Feature;
import org.togglz.core.manager.FeatureManager;
import org.togglz.core.manager.FeatureManagerBuilder;
import org.togglz.core.manager.TogglzConfig;
import org.togglz.core.repository.StateRepository;
import org.togglz.core.repository.jdbc.JDBCStateRepository;
import org.togglz.core.user.SimpleFeatureUser;
import org.togglz.core.user.UserProvider;

import com.icoderoad.togglzflag.enums.MyFeatures;


@Configuration
public class TogglzFeatureConfig implements TogglzConfig {

    private final DataSource dataSource;

    public TogglzFeatureConfig(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    public Class getFeatureClass() {
        return MyFeatures.class; // 返回定义的特性枚举类
    }

    @Override
    public StateRepository getStateRepository() {
        // 使用 JDBC 存储特性状态
        return JDBCStateRepository.newBuilder(dataSource).build();
    }

    @Override
    public UserProvider getUserProvider() {
        // 定义用户提供者
        return () -> new SimpleFeatureUser("admin", true);
    }

    @Bean
    public FeatureManager featureManager() {
        return new FeatureManagerBuilder()
                .featureEnum(MyFeatures.class) // 绑定特性枚举类
                .stateRepository(getStateRepository()) // 设置状态存储库
                .userProvider(getUserProvider()) // 设置用户提供者
                .build();
    }
}

通过这样的配置,你可以灵活地管理 Spring Boot 应用中的特性开关,并使用数据库来持久化特性状态。

如果大家想使用内存中的状态存储(InMemoryStateRepository),可以在 getStateRepository() 方法中返回一个简单的内存存储:

@Override
public StateRepository getStateRepository() {
    return new InMemoryStateRepository();
}

数据库配置

如果你使用 JDBCStateRepository 来持久化特性状态,需要确保你的数据库中有一张存储特性开关状态的表。Togglz 提供了创建这张表的 SQL 脚本:

CREATE TABLE `TOGGLZ` (
  `FEATURE_NAME` varchar(100) NOT NULL,
  `FEATURE_ENABLED` int(11) NOT NULL,
  `STRATEGY_ID` varchar(200) DEFAULT NULL,
  `STRATEGY_PARAMS` varchar(2000) DEFAULT NULL,
  PRIMARY KEY (`FEATURE_NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

配置 application.yml

在 application.yml 中配置数据库连接信息:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/togglz_db
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

定义特性开关枚举类

在 Togglz 中,特性开关通过枚举类来管理,每个枚举值代表一个开关。该枚举类定义了应用程序中的所有特性开关,并且可以为每个特性开关指定标签和默认状态。

package com.icoderoad.togglzflag.enums;

import org.togglz.core.Feature;
import org.togglz.core.annotation.EnabledByDefault;
import org.togglz.core.annotation.Label;


public enum MyFeatures implements Feature {

    @Label("功能一")
    FEATURE_ONE,

    @EnabledByDefault
    @Label("功能二")
    FEATURE_TWO;
}

实现 API 接口

我们创建一个控制器来处理特性开关的查询和更新,通过 RESTful API 实现后端和前端的交互。

package com.icoderoad.togglzflag.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.togglz.core.Feature;
import org.togglz.core.manager.FeatureManager;
import org.togglz.core.repository.FeatureState;

import com.icoderoad.togglzflag.enums.MyFeatures;

@RestController
@RequestMapping("/api/features")
public class FeatureToggleController {

    @Autowired
    private FeatureManager featureManager;

    
    @GetMapping
    public Map getFeatures() {
        Map features = new HashMap<>();
        features.put("featureOne", featureManager.isActive(MyFeatures.FEATURE_ONE));
        features.put("featureTwo", featureManager.isActive(MyFeatures.FEATURE_TWO));
        return features;
    }

    
    @PostMapping("/toggle")
    public Map toggleFeatures(@RequestBody Map featureStates) {
        try {
            for (Map.Entry entry : featureStates.entrySet()) {
                String featureName = entry.getKey();
                boolean enabled = entry.getValue();

                Feature feature = getFeature(featureName);
                if (feature != null) {
                    featureManager.setFeatureState(new FeatureState(feature, enabled));
                } else {
                    return Map.of("status", "error", "message", "未找到特性 " + featureName);
                }
            }
            return Map.of("status", "success", "message", "所有特性状态已更新");
        } catch (Exception e) {
            return Map.of("status", "error", "message", "更新特性状态时发生错误");
        }
    }

    private Feature getFeature(String featureName) {
        if ("featureOne".equalsIgnoreCase(featureName)) {
            return MyFeatures.FEATURE_ONE;
        } else if ("featureTwo".equalsIgnoreCase(featureName)) {
            return MyFeatures.FEATURE_TWO;
        }
        return null;
    }
}

前端实现

在前端,我们使用 Thymeleaf 渲染数据,并结合 jQuery 和 Bootstrap 实现用户友好的特性开关管理界面。

在 src/main/resources/templates/index.html 文件中使用 Thymeleaf 模板显示配置信息:




    
    特性开关管理
    
    


    

结论

通过结合 Togglz 框架和 Spring Boot3.3,我们成功实现了基于 API 和 UI 的特性开关管理方案。特性开关管理不仅为应用程序提供了更高的灵活性,还可以帮助团队实现无缝的功能发布。Togglz 的简单集成、持久化配置和丰富的扩展性为特性开关管理提供了理想的解决方案。在未来的工作中,这一方案可以进一步优化,以支持更多特性控制的复杂场景,如按用户组启用、按环境发布等。

来源:路条编程内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯