第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

超詳細(xì)!Spring Boot 項(xiàng)目與 Togglz 深度整合實(shí)現(xiàn)特性開關(guān)全攻略

標(biāo)簽:
SpringBoot

在当今快速迭代的软件开发领域,如何高效地管理和控制应用程序的功能特性,成为了开发者们面临的重要挑战。想象一下,在不重启应用的情况下,就能灵活地启用或禁用某些功能,根据不同的用户群体、环境条件等因素,动态调整应用的功能展示和使用权限,这是不是非常酷?而 Togglz,这个强大的 Java 应用功能开关框架,就能帮助我们轻松实现这些功能。

一、认识 Togglz:功能开关框架的魅力

Togglz 是一款专为 Java 应用打造的功能开关框架,它就像是应用功能的 “智能管家”,允许开发者在不重启应用的情况下,便捷地启用或禁用功能。以下是 Togglz 的几大关键特性,让它在众多框架中脱颖而出

  • 功能开关:Togglz 通过定义功能开关,精准控制哪些功能对用户可见或可用,为功能管理提供了清晰的界限和规则。

  • 动态配置:支持在运行时更改功能开关的状态,无需重新部署应用程序,大大提高了开发和运维的效率,让功能调整更加灵活及时。

  • 多种存储方式:可以将功能开关的状态存储在不同的后端,如数据库、文件系统或内存中,满足不同场景下的数据存储和管理需求。

  • 集成简单:与 Spring、CDI 等主流框架有良好的集成,易于在现有项目中引入,降低了技术升级和功能扩展的成本。

  • 用户界面:提供了一个直观的管理界面,方便管理员查看和修改功能开关的状态,操作便捷,一目了然。

二、Togglz 的常用应用场景

Togglz 的应用场景十分广泛,在软件开发的各个环节都能发挥重要作用:

  • 逐步发布新功能:

在大型项目中,新功能可能需要逐步发布给部分用户,以确保其稳定性和性能。Togglz 可以帮助你精准控制哪些用户可以看到新功能,实现平滑的功能上线。

  • A/B 测试:

通过功能开关,你可以轻松地为不同用户群体提供不同的功能版本,从而进行 A/B 测试,评估新功能的效果,为产品优化提供数据支持。

  • 紧急回滚:

如果新功能在生产环境中出现问题,可以快速关闭功能开关,而无需重新部署整个应用,从而减少停机时间,保障业务的连续性。

  • 内部测试:

在功能开发阶段,可以仅对内部测试人员开放新功能,确保功能在正式发布前经过充分测试,提高产品质量。

  • 环境隔离:

不同的环境(如开发、测试、生产)可以有不同的功能开关配置,确保每个环境中的功能状态符合需求,避免环境差异带来的问题。

  • 按需启用高级功能:

对于付费用户或特定客户,可以通过功能开关控制高级功能的访问权限,实现差异化服务,提升用户体验和商业价值。

  • 性能优化:

某些功能可能会影响应用性能,可以在生产环境中临时关闭这些功能,以监控和优化性能,保障应用的高效运行。

三、实战演示:Spring Boot 项目与 Togglz 的整合

接下来,我们通过一个实际的示例,详细演示如何在 Spring Boot 项目中与 Togglz 整合,实现特性开关的功能。我们以模拟在正式环境能获取某种资源,其他环境获取不到为例,逐步展开操作

1、引入 Togglz 相关依赖

在项目的 pom.xml 文件中引入 Togglz 的依赖:


<dependency>

<groupId>org.togglz</groupId>

<artifactId>togglz-spring-boot-starter</artifactId>

<version>${togglz.version}</version>

</dependency>

  

2、定义功能开关

创建一个枚举类来定义功能开关:


public  enum EnvFeature implements Feature {

  

@Label("生产环境")

PROD,

  

@Label("预发布环境")

UAT,

  

@Label("测试环境")

TEST,

  
  

@EnabledByDefault

@Label("开发环境")

DEV;

  

public  boolean isActive() {

return FeatureContext.getFeatureManager().isActive(this);

}

  

public  static EnvFeature getEnvFeature(String env){

EnvFeature[] envFeatures = EnvFeature.values();

for (EnvFeature envFeature : envFeatures) {

if(envFeature.name().equalsIgnoreCase(env)){

return envFeature;

}

}

throw  new IllegalArgumentException("env参数不合法");

}

}

  

@Label注解用于为功能开关提供一个友好的显示名称,方便在管理界面中识别;@EnabledByDefault注解用于标记某个功能开关在默认情况下是启用的

3、定义togglz功能管理配置

实现TogglzConfig接口,自定义功能开关的管理方式:


/**

* @see <a >...</a>

*/

  

@Slf4j

@RequiredArgsConstructor

public  class EnvTogglzConfig implements TogglzConfig , InitializingBean {

  

private  final ObjectProvider<List<StateRepositoryFactory>> listObjectProvider;

private  final EnvTogglzProperties envTogglzProperties;

  

private Map<String,StateRepositoryFactory> stateRepositoryMap;

@Override

public Class<? extends Feature> getFeatureClass() {

// 返回定义功能开关的枚举类

return EnvFeature.class;

}

  

/***

* @see <a ></a>

* @return

*/

@Override

public StateRepository getStateRepository() {

//配置功能开关状态的存储方式

if(stateRepositoryMap == null || stateRepositoryMap.isEmpty()){

log.warn("stateRepositoryFactories is empty,select inMemoryStateRepository");

return  new InMemoryStateRepository();

}

  

return stateRepositoryMap.get(envTogglzProperties.getStateRepositoryType()).create();

  

}

  

/**

* @see <a ></a>

* @return

*/

@Override

public UserProvider getUserProvider() {

// 提供功能开关的提供者,返回当前登录的用户对象

return  new SingleUserProvider("lybgeek", true);

}

  

@Override

public  void afterPropertiesSet() {

  

List<StateRepositoryFactory> stateRepositoryFactories = listObjectProvider.getIfAvailable();

if(CollectionUtils.isEmpty(stateRepositoryFactories)){

return;

}

stateRepositoryMap = new HashMap<>(stateRepositoryFactories.size());

stateRepositoryFactories.forEach(stateRepositoryFactory -> stateRepositoryMap.put(stateRepositoryFactory.supportType(),stateRepositoryFactory));

  
  

}

}

  

在这个配置类中,我们主要完成了以下几个配置点:

  • 功能开关类:

指定定义了所有功能开关的枚举类。

  • 用户解析:

提供一个方法来解析当前用户,这对于基于用户的功能开关策略非常重要。

  • 状态持久化:

配置功能开关状态的存储方式,例如内存、数据库、文件等。

  • 策略配置:

配置功能开关的激活策略,例如基于用户角色、请求参数、时间等

3、创建功能管理器

创建一个FeatureManager的 Bean:


@Bean

@ConditionalOnMissingBean

public FeatureManager featureManager(EnvTogglzConfig envTogglzConfig){

return  new FeatureManagerBuilder()

.featureEnum(envTogglzConfig.getFeatureClass())

.stateRepository(envTogglzConfig.getStateRepository())

.userProvider(envTogglzConfig.getUserProvider())

.build();

}

  

FeatureManager提供了一系列的方法来查询和修改功能开关的状态,以及执行与功能开关相关的操作,包括查询功能开关状态、修改功能开关状态、获取功能开关元数据、执行功能开关策略等。

5、使用功能开关

这边炫技一下,我们使用bytebuddy来实现一个切面,以更灵活地使用功能开关。

a、 项目pom引入bytebuddy依赖


<dependency>

<groupId>net.bytebuddy</groupId>

<artifactId>byte-buddy</artifactId>

<version>${bytebuddy.version}</version>

</dependency>

b、 自定义激活功能开关注解


@Retention(RetentionPolicy.RUNTIME)

@Documented

@Target(ElementType.METHOD)

public  @interface EnvTogglz {

  

String activeEnv() default  "${lybgeek.togglz.env:dev}";

}

  

c、 创建代理

实现InvocationHandler接口,创建一个代理类:


@RequiredArgsConstructor

public  class EnvTogglzInvocationHandler implements InvocationHandler {

  

private  final String activeEnv;

private  final Object target;

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

if(StringUtils.isEmpty(activeEnv)){

return method.invoke(target, args);

}

  

if(EnvFeature.getEnvFeature(activeEnv).isActive()){

return method.invoke(target, args);

}

  

throw  new EnvTogglzException("非法访问", HttpStatus.FORBIDDEN.value());

}

}

核心代码通过判断功能开关是否激活,来决定是否执行目标方法。

d、 创建 bytebuddy 代理工厂

创建一个代理工厂类,用于生成代理对象:


@Slf4j

public  final  class EnvTogglzProxyFactory {

private EnvTogglzProxyFactory(){}

  

public  static <T> T createProxy(T target,String activeEnv) {

  

Class proxy = new ByteBuddy()

.subclass(target.getClass())

.method(any())

.intercept(InvocationHandlerAdapter.of(new EnvTogglzInvocationHandler(activeEnv,target)))

.attribute(MethodAttributeAppender.ForInstrumentedMethod.INCLUDING_RECEIVER)

.annotateType(target.getClass().getAnnotations())

.make()

.load(EnvTogglzProxyFactory.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)

.getLoaded();

  

try {

return (T)proxy.getDeclaredConstructor().newInstance();

} catch (InstantiationException | InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {

log.error("create proxy error",e);

}

  

return null;

  

}

e、 通过bytebuddy增强

实现SmartInstantiationAwareBeanPostProcessor接口,对 Bean 进行增强处理:


@Slf4j

public  class EnvTogglzProxyBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor, ApplicationContextAware {

  

private ApplicationContext applicationContext;

  

@Override

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

EnvTogglz envTogglz = getEnvTogglz(bean);

if(envTogglz != null){

String activeEnv = applicationContext.getEnvironment().resolvePlaceholders(envTogglz.activeEnv());

return EnvTogglzProxyFactory.createProxy(bean,activeEnv);

}

  

return bean;

  

}

  
  
  

private EnvTogglz getEnvTogglz(Object bean) {

boolean aopProxy = AopUtils.isAopProxy(bean);

Class targetClz = bean.getClass();

if(aopProxy){

targetClz = AopUtils.getTargetClass(bean);

}

  

for (Method declaredMethod : targetClz.getDeclaredMethods()) {

EnvTogglz envTogglz = AnnotationHelper.getAnnotation(declaredMethod, EnvTogglz.class);

if(envTogglz != null){

return envTogglz;

}

}

  

return null;

}

  
  

@Override

public  void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

this.applicationContext = applicationContext;

}

  
  

}

  

6、测试功能开关

创建一个测试的 Controller:


@RestController

@RequestMapping("test")

@RequiredArgsConstructor

public  class TestController {

  

@GetMapping("info")

@EnvTogglz

public ResponseEntity<String> info(){

return ResponseEntity.ok("生产环境-资源");

}

}

  

通过浏览器访问http://localhost:8080/test/info

请在此添加图片描述

发现访问不到正式的资源,因为我们默认激活的环境开关是DEV

要使用 Togglz 提供的控制面板,首先在项目的 pom.xml 文件中配置如下依赖:


<!-- Togglz 控制台依赖,用于管理特性开关 -->

<dependency>

<groupId>org.togglz</groupId>

<artifactId>togglz-console</artifactId>

<version>${togglz.version}</version>

</dependency>

然后在application.yml文件中激活控制台:


togglz:

console:

enabled: true

path: /togglz

secured: true

secured表示开启访问权限,权限取决于配置的UserProvider。浏览器访问http://localhost:8080/togglz

请在此添加图片描述

然后将生产环境改为激活状态

请在此添加图片描述

最后再次访问http://localhost:8080/test/info

请在此添加图片描述

,即可获取到资源。

四、总结

通过上述详细的步骤,我们成功地在 Spring Boot 项目中与 Togglz 进行了整合,实现了特性开关的功能。Togglz 为我们提供了一种灵活、高效的功能管理方式,能够帮助我们更好地应对软件开发过程中的各种挑战。本文只是对 Togglz 的一个入门介绍,如果大家对 Togglz 的源码感兴趣,还可以深入研究,其中的一些实现思路和技巧可以为我们的日常开发带来很多启发。如果想对 Togglz 有更深入的理解,可以查看官方网站:

五、demo链接

本文的示例代码可以在以下链接中获取:

點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評(píng)論
  • 收藏
  • 共同學(xué)習(xí),寫下你的評(píng)論
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會(huì)直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消