fegin实现方法级别注解超时配置

fegin实现方法级别注解超时配置

测试的3.18新版本已经支持方法中参数带有Options 也可以自定义配置, Options options = findOptions(argv);;

使用该注解方式需配合AOP使用!

原理是包装自己的client客户端, 替换框架的客户端!
应用到生产环境需自己充验证测试

1.0 注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FeignTimeout {/*** 连接超时时间* @return*/int connectTimeoutMillis() default 10000;/*** 读取超时时间* @return*/int readTimeoutMillis() default 60000;
}

2.0 包装的客户端FeignTimeoutClient

import feign.Client;
import feign.Request;
import feign.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.IOException;
import java.util.Objects;public class FeignTimeoutClient implements Client {private static final Logger log = LoggerFactory.getLogger(FeignTimeoutClient.class);private static final ThreadLocal<Request.Options> NOW_OPTIONS = new ThreadLocal<>();private final Client delegate;private FeignTimeoutClient(Client delegate){this.delegate = delegate;}public static Client wrap(Client client){return new FeignTimeoutClient(client);}public static void nowOptions(Request.Options options){NOW_OPTIONS.set(options);}public static void nowOptionsClear(){NOW_OPTIONS.remove();}@Overridepublic Response execute(Request request, Request.Options options) throws IOException {// 如果未取到当前上下文的 自定义超时时间 则直接使用默认的,如果取到了则用特殊的Request.Options optionsNow = NOW_OPTIONS.get();if(Objects.nonNull(optionsNow)){log.info("feign命中自定义超时:url="+request.url()+";options.connectTimeoutMillis="+ optionsNow.connectTimeoutMillis()+",options.readTimeoutMillis="+optionsNow.readTimeoutMillis());return delegate.execute(request,optionsNow);}return delegate.execute(request,options);}
}

3.0 包装FeignContext

FeignTimeoutFeignContext上下文

import feign.Client;
import feign.Feign;
import lombok.SneakyThrows;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FeignContext;
import org.springframework.util.ReflectionUtils;import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;public class FeignTimeoutFeignContext extends FeignContext {private static final Logger log = LoggerFactory.getLogger(FeignTimeoutFeignContext.class);private final FeignContext delegate;private FeignTimeoutFeignContext(FeignContext delegate) {this.delegate = delegate;}@Overridepublic <T> T getInstance(String name, Class<T> type) {T instance = delegate.getInstance(name, type);return (T) wrapIfShould(instance);}@Overridepublic <T> Map<String, T> getInstances(String name, Class<T> type) {Map<String, T> instances = delegate.getInstances(name, type);if (MapUtils.isNotEmpty(instances)) {Map<String, T> convertedInstances = new HashMap<>();for (Map.Entry<String, T> entry : instances.entrySet()) {convertedInstances.put(entry.getKey(), (T) wrapIfShould(entry.getValue()));}return convertedInstances;}return instances;}@SneakyThrowsprivate Object wrapIfShould(Object instance) {if (instance instanceof Feign.Builder) {Field field = instance.getClass().getDeclaredField("client");field.setAccessible(true);Client client = (Client) ReflectionUtils.getField(field, instance);if (client instanceof FeignTimeoutClient) {return instance;}Client wrap = FeignTimeoutClient.wrap(client);ReflectionUtils.setField(field, instance, wrap);}if (instance instanceof Client && !(instance instanceof FeignTimeoutClient)) {Object client = instance;return FeignTimeoutClient.wrap((Client) client);}return instance;}public static FeignTimeoutFeignContext wrap(FeignContext context) {return new FeignTimeoutFeignContext(context);}
}

bean后置处理器进行包装

package com.zhihao.fegin;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.cloud.openfeign.FeignContext;
public class FeignTimeoutBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// 对FeignContext进行包装if(bean instanceof FeignContext && !(bean instanceof FeignTimeoutFeignContext)){return FeignTimeoutFeignContext.wrap(((FeignContext) bean));}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
}

4.0 配置AOP注解拦截设置超时

package com.zhihao.fegin;
import feign.Request;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.core.annotation.AnnotationUtils;
import java.util.Objects;
public class FeignTimeoutMethodInterceptor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {try {// 先查找当前方法以及方法所在类上的注解FeignTimeout feignTimeout = AnnotationUtils.findAnnotation(invocation.getMethod(), FeignTimeout.class);if(Objects.nonNull(feignTimeout)){FeignTimeoutClient.nowOptions(new Request.Options(feignTimeout.connectTimeoutMillis(), feignTimeout.readTimeoutMillis()));}return invocation.proceed();} finally {FeignTimeoutClient.nowOptionsClear();}}
}

5.0 使用配置类加入IOC容器

@Configuration
// 如果后续有配置需要在FeignClientsConfiguration初始化前使用则需要该注解, 配合@condition使用
// @AutoConfigureBefore(FeignClientsConfiguration.class)
public class FeignConfiguration {@Beanpublic FeignTimeoutBeanPostProcessor feignTimeoutBeanPostProcessor(){return new FeignTimeoutBeanPostProcessor();}@Beanpublic DefaultPointcutAdvisor feignTimeoutPointcutAdvisor(){FeignTimeoutMethodInterceptor interceptor = new FeignTimeoutMethodInterceptor();AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();pointcut.setExpression("@annotation(com.zhihao.spring.cloud.fegin.ext.timeout.FeignTimeout)");// 配置增强类advisorDefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();advisor.setPointcut(pointcut);advisor.setAdvice(interceptor);return advisor;}
}

6.0 使用

/*** @Author: ZhiHao* @Date: 2023/8/26 14:33* @Description:* @Versions 1.0**/
@FeignClient(name = "feignTimeOutTest",url = "https://test-zhiha.plus")
public interface FeignTimeOutTest {@GetMapping("/masterPriceManager/detail")@FeignTimeout(connectTimeoutMillis = 500,readTimeoutMillis = 300)Map<String, Object> detail(@RequestParam("masterId") Long masterId);
}

7.0 结果:

pPNDPOK.png

ail")
@FeignTimeout(connectTimeoutMillis = 500,readTimeoutMillis = 300)
Map<String, Object> detail(@RequestParam(“masterId”) Long masterId);
}


7.0 结果:[[外链图片转存中...(img-YhTVhjsr-1693034378942)]](https://imgse.com/i/pPNDPOK)1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/108154.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# .aspx网页获取RFID读卡器HTTP协议提交的访问文件Request获得卡号、机号,Response回应驱动读卡器显示响声

本示例使用的设备&#xff1a;RFID网络WIFI无线TCP/UDP/HTTP可编程二次开发读卡器POE供电语音-淘宝网 (taobao.com) 服务端代码&#xff1a; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.…

【QT】重写QAbstractLIstModel,使用ListView来显示多列数据

qt提供了几个视图来进行信息的列表显示&#xff0c;QListView可以用来显示继承QStractListModel的字符串列表中的字符串&#xff0c;默认的模型里面只包含一列的内容&#xff1a; 这里以qml为例子&#xff0c;先新建一个qml的项目&#xff0c;示例代码如下&#xff1a; 先创建一…

深度学习3. 强化学习-Reinforcement learning | RL

强化学习是机器学习的一种学习方式&#xff0c;它跟监督学习、无监督学习是对应的。本文将详细介绍强化学习的基本概念、应用场景和主流的强化学习算法及分类。 目录 什么是强化学习&#xff1f; 强化学习的应用场景 强化学习的主流算法 强化学习(reinforcement learning) …

产品经理的六步路线图:快速制定你的产品计划

2023年的软件世界比以往任何时候都发展得更快&#xff0c;并充满了各种变量。而这将会以各种方式影响产品路线图的落地执行与实现。随着问题越来越多&#xff0c;世界需要不断发展的解决方案。因此&#xff0c;本文结合产品路线图当前存在的共性问题&#xff0c;借鉴企业的成功…

wxpython:wx.html2 是好用的 WebView 组件

wxpython : wx.html2 是好用的 WebView 组件。 wx.html2 是wxPython扩展模块中封装得干净漂亮的模块之一&#xff0c;它被设计为允许为每个端口创建多个后端&#xff0c;尽管目前只有一个可用。它与wx.html.HtmlWindow 的不同之处在于&#xff0c;每个后端实际上都是一个完整的…

图像检索,目标检测map的实现

一、图像检索指标Rank1,map 参考&#xff1a;https://blog.csdn.net/weixin_41427758/article/details/81188164?spm1001.2014.3001.5506 1.Rank1: rank-k&#xff1a;算法返回的排序列表中&#xff0c;前k位为存在检索目标则称为rank-k命中。 常用的为rank1&#xff1a;首…

官方项目《内容示例》中Common UI部分笔记: 1.1 Activatable Widgets

本文主要面向UMG以及Common UI的初学者 文章目录 效果展示概要Activate和Deactivate可见性绑定UI动画设置Common Activatable Widget的默认焦点 效果展示 概要 这个例子非常简单&#xff0c;定义了13个Common Activatable Widget CommonUI_ActivatableWidgets相当于一个容器包…

UITableView自定义TableHeader和TableFooter

UITableView自定义TableHeader和TableFooter 我猜你希望的效果是这样的 我猜你希望的效果是这样的 自定义页眉视图 让我们创建一个文件名 UITableViewHeaderFooterView 的 CustomerHeaderView 子类。 现在让我们创建视图的 Xib 文件并将其命名为 CustomHeaderView。 更改高度标…

第 360 场 LeetCode 周赛题解

A 距离原点最远的点 串中的 “_” 处要么都向左走要么都向右走 class Solution { public:int furthestDistanceFromOrigin(string moves) {int t 0;for (auto x: moves)if (x ! R)t--;elset;int res abs(t);t 0;for (auto x: moves)if (x ! L)t;elset--;res max(res, abs(t…

C语言基础之——指针(下)

前言&#xff1a;本篇文章将继续讲解有关指针的剩余基础知识。 学无止境&#xff0c;一起加油叭&#xff01;&#xff01; 目录 一.指针运算 1.指针 - 整数 2.指针的关系运算 3.指针 - 指针 二.指针与数组 三.二级指针 四.指针数组 总结 一.指针运算 指针运算包括以下三…

可解释性的相关介绍

一、可解释性的元定义&#xff08;Meta-definitions of Interpretability&#xff09; The extent to which an individual can comprehend the cause of a model’s outcome. [1]The degree to which a human can consistently predict a model’s outcome. [2] 可解释性&am…

小研究 - Java虚拟机垃圾收集器的性能分析与调节

垃圾收集器是&#xff2a;&#xff41;&#xff56;&#xff41;虚拟机&#xff08;&#xff2a;&#xff36;&#xff2d;&#xff09;的核心组成部分之一&#xff0c;对&#xff2a;&#xff41;&#xff56;&#xff41;虚拟机的性能有非常重要的影响。本文将介绍&#xff2…

十几款拿来就能用的炫酷表白代码

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;小白零基础《Python入门到精通》 表白代码 1、坐我女朋友好吗&#xff0c;不同意就关机.vbs2、坐我女朋友好吗&…

<八> objectARX开发:动态拖动Jig创建自定义实体

1、介绍 接上一篇文章,在某些情况下,CAD中的实体对象初始参数并不是固定的,我们需要通过jig动态拖动方式来绘制自定义实体,下面就用一个简单的例子来介绍一下自定义实体动态绘制。   实体形状:包括实体夹点和文字夹点拖动实现。 2、效果 3、源码 static void RYMyGrou…

CAN总线学习——物理层、数据链路层、CANopen协议

1、CAN总线介绍 1.1、CAN总线描述 (1)CAN总线支持多节点通信&#xff0c;但是节点不分区主从&#xff0c;也就是不存在一个节点来负责维护总线的通信&#xff1b;这点可以和I2C总线对对比&#xff0c;I2C是一主多从模式&#xff1b; (2)是差分、异步、串行总线&#xff0c;采用…

华为OD机试 - 求满足条件的最长子串的长度 - 双指针(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…

无人驾驶领域的软件测试该如何开展?

无人驾驶汽车使用自主决策和控制系统&#xff0c;这种系统通常由多个软件和硬件组件组成。软件测试是必要的&#xff0c;因为它可以确保无人驾驶汽车的软件系统达到高度可靠性和安全性&#xff0c;以及提高无人驾驶汽车的性能和可靠性。 因此无人驾驶汽车是一定要进行严格的软件…

关于类的隐形生成函数

https://www.youtube.com/watch?ve8Cw17p_BiU&listPL5jc9xFGsL8FWtnZBeTqZBbniyw0uHyaH&index6 https://www.youtube.com/watch?vKMSYmY74AEs&listPLE28375D4AC946CC3&index4 如果只有copy asignment operator, 那么default construct will be generated as…

PyCharm软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 PyCharm是一种集成开发环境&#xff08;IDE&#xff09;&#xff0c;专门为Python开发者设计。它是由捷克软件公司JetBrains开发的&#xff0c;为Python开发人员提供了高效、易用和功能丰富的工具集。 以下是PyCharm软件的主要…

【C语言】操作符大全(保姆级介绍)

&#x1f6a9;纸上得来终觉浅&#xff0c; 绝知此事要躬行。 &#x1f31f;主页&#xff1a;June-Frost &#x1f680;专栏&#xff1a;C语言 &#x1f525;该篇将详细介绍各种操作符的功能。 目录&#xff1a; &#x1f4d8; 前言① 算术操作符②移位操作符③位操作符④赋值操…