Spring Cloud OpenFeign
- 概述
Feign是一个声明式web服务客户端。可以像写接口一样定义http客户端。Feign还支持可插拔的编码器和解码器。Spring Cloud增加了对Spring MVC注释和使用Spring Web中默认使用的HttpMessageConverter的支持。Spring Cloud集成了Ribbon和Eureka,以及Spring Cloud LoadBalancer,在使用Feign时提供负载均衡的http客户端。
1.1 如何使用feign
Application
@SpringBootApplication
@EnableFeignClients
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}
StoreClient.java
@FeignClient("stores")
public interface StoreClient {@RequestMapping(method = RequestMethod.GET, value = "/stores")List<Store> getStores();@RequestMapping(method = RequestMethod.GET, value = "/stores")Page<Store> getStores(Pageable pageable);@RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json")Store update(@PathVariable("storeId") Long storeId, Store store);
}
在@FeignClient注释中,字符串值(上面的“stores”)是任意的客户端名称,用于创建Ribbon或Spring Cloud LoadBalancer。还可以使用URL属性(绝对值或仅主机名)指定URL。应用程序上下文中bean的名称是接口的完全限定名。要指定自己的别名值,可以使用@FeignClient注释的唯一限定值。上面的负载均衡客户端将希望发现“存储”服务的物理地址。如果您的应用程序是Eureka客户端,那么它将解析Eureka服务注册表中的服务。如果不想使用Eureka,可以使用SimpleDiscoveryClient在外部配置中配置服务器列表。
为了保持向后兼容性,将用作默认的负载均衡器实现。但是,Spring Cloud Netflix Ribbon现在处于维护,所以我们建议改用Spring Cloud LoadBalancer。为此,请设置spring.cloud.loadbalancer.ribbon为false
1.2 覆盖 feign 默认配置
spring cloud对外支持的一个核心概念是可命名客户端。每个feign client都是一个组件集合的一部分,这些组件一起工作以按需联系远程服务器,并且该集成有一个名称,您可以使用@FeignClient注释将其命名为应用程序开发人员。spring cloud使用FeignClientsConfiguration为每个命名客户端创建一个新的集成,作为ApplicationContext。它包含(除其他外)一个feign.Decoder,一个feign.Encoder,和feign.Contract. 可以通过使用@FeignClient注释的contextId属性覆盖该集合的名称。
spring cloud允许您通过使用@FeignClient声明附加配置(在FeignClientsConfiguration之上)来完全控制feign client。
例子:
@FeignClient(name = "stores", configuration = FooConfiguration.class)
public interface StoreClient {//..
}
在这种情况下,客户端由FeignClientsConfiguration中已经存在的组件和FooConfiguration中的任何组件组成(后者将覆盖前者)。
FooConfiguration不需要用@Configuration注释。但是,如果是,那么要注意将它从任何可能包含此配置的@ComponentScan中排除,因为它将成为feign的默认源。feign.Decoder, feign.Encoder, feign.Contract等,如有明确规定。这可以通过将其放在来自任何@ComponentScan或@SpringBootApplication的独立的、不重叠的包中来避免,或者可以在@ComponentScan中显式地排除它。
注意:
1) serviceId属性现在已被弃用,取而代之的是name属性。
2) 除了更改ApplicationContext集成的名称之外,使用@FeignClient注释的contextId,它将覆盖客户端名称的别名,并且它将被用作为该客户端创建的配置bean的名称的一部分。
3)以前,使用url属性不需要name属性。现在需要使用name属性。
在name和url属性中支持占位符。
@FeignClient(name = "${feign.name}", url = "${feign.url}")
public interface StoreClient {//..
}
Spring Cloud OpenFeign默认为feign提供以下bean (bean类型 bean名称:类名)
Decoder feignDecoder: ResponseEntityDecoder (包含一个 SpringDecoder)
Encoder feignEncoder: SpringEncoder
Logger feignLogger: Slf4jLogger
Contract feignContract: SpringMvcContract
Feign.Builder feignBuilder: HystrixFeign.Builder
Client feignClient: 如果Ribbon在类路径中并且被启用,那么它就是LoadBalancerFeignClient,
否则,如果Spring Cloud LoadBalancer在类路径中,则使用FeignBlockingLoadBalancerClient。
如果它们都不在类路径中,则使用默认的feign client。
spring-cloud-starter-openfeign同时支持spring-cloud-starter-netflix-ribbon和spring-cloud-starter- load-balancer。但是,由于它们是可选的依赖项,您需要确保您想要使用的依赖项已添加到您的项目中。
OkHttpClient和ApacheHttpClient feign clients可以通过设置feign.okhttpfeign.httpclient或feign.httpclient.enabled为true,并将它们放在类路径上。你可以通过提供一个自定义bean来自定义feign client,当使用Apache client时提供一个org.apache.http.impl.client.CloseableHttpClient的bean,使用OK client时提供一个okhttp3.OkHttpClient的bean.
Spring Cloud OpenFeign默认不提供以下bean给feign,但是仍然从应用上下文中查找这些类型的bean来创建feign客户端:
1)Logger.Level
2)Retryer
3)ErrorDecoder
4)Request.Options
5)Collection
6)SetterFactory
7)QueryMapEncoder
默认情况下创建一个类型为Retryer的Retryer.NEVER_RETRY bean,这将禁用重试。请注意,这种重试行为与Feign默认不同,在Feign默认中,它将自动重试IOExceptions,并将它们视为暂时的网络相关异常,以及从ErrorDecoder抛出的任何RetryableException。
创建其中一种类型的bean并将其放置在@FeignClient配置中(如上面的FooConfiguration)允许您覆盖所描述的每个bean。
例子: 这将用feign.Contract.Default替换SpringMvcContract。并将RequestInterceptor添加到RequestInterceptor的集合中。
@Configuration
public class FooConfiguration {@Beanpublic Contract feignContract() {return new feign.Contract.Default();}@Beanpublic BasicAuthRequestInterceptor basicAuthRequestInterceptor() {return new BasicAuthRequestInterceptor("user", "password");}
}
@FeignClient也可以使用配置属性进行配置
feign:client:config:feignName:connectTimeout: 5000readTimeout: 5000loggerLevel: fullerrorDecoder: com.example.SimpleErrorDecoderretryer: com.example.SimpleRetryerrequestInterceptors:- com.example.FooRequestInterceptor- com.example.BarRequestInterceptordecode404: falseencoder: com.example.SimpleEncoderdecoder: com.example.SimpleDecodercontract: com.example.SimpleContract
默认配置可以在@EnableFeignClients属性defaultConfiguration中以类似的方式指定,如上所述。不同之处在于此配置将应用于所有feign client。
如果您喜欢使用配置属性来配置所有的@FeignClient,您可以使用默认的feign名称创建配置属性。
feign:client:config:default:connectTimeout: 5000readTimeout: 5000loggerLevel: basic
如果我们同时创建@Configuration bean和配置属性,配置属性会被加载。它将覆盖@Configuration值。但是如果您想将优先级更改为@Configuration,您可以将feign.client.default-to-properties更改为false。
如果我们想创建多个具有相同名称或url的feign client,以便它们指向相同的服务器,但每个客户机都有不同的自定义配置,那么我们必须使用@FeignClient的上下文tid属性,以避免这些配置bean的名称冲突。
@FeignClient(contextId = "fooClient", name = "stores", configuration = FooConfiguration.class)
public interface FooClient {//..
}@FeignClient(contextId = "barClient", name = "stores", configuration = BarConfiguration.class)
public interface BarClient {//..
}
还可以配置FeignClient不从父上下文继承bean。你可以通过重写FeignClientConfigurer bean中的inheritParentConfiguration()来实现:
@Configuration
public class CustomConfiguration{@Bean
public FeignClientConfigurer feignClientConfigurer() {return new FeignClientConfigurer() {@Overridepublic boolean inheritParentConfiguration() {return false;}};}
}
1.3 手动创建 feign client
在某些情况下,可能有必要定制您的feign客户端,而使用上述方法是不可能的。在这种情况下,您可以使用Feign Builder API创建feign client。下面是一个示例,它创建了两个具有相同接口的feign客户端,但为每个客户端配置了一个单独的请求拦截器。
// FeignClientsConfiguration是Spring Cloud OpenFeign的默认配置
// PROD-SVC是feign调用的服务名称
// Feign Contract提供了SpringMVC注解的支持
@Import(FeignClientsConfiguration.class)
class FooController {private FooClient fooClient;private FooClient adminClient;@Autowiredpublic FooController(Decoder decoder, Encoder encoder, Client client, Contract contract) {this.fooClient = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract).requestInterceptor(new BasicAuthRequestInterceptor("user", "user")).target(FooClient.class, "https://PROD-SVC");this.adminClient = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract).requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin")).target(FooClient.class, "https://PROD-SVC");}
}
1.4 feign继承支持
public interface UserService {@RequestMapping(method = RequestMethod.GET, value ="/users/{id}")User getUser(@PathVariable("id") long id);
}@RestController
public class UserResource implements UserService {
}package project.user;@FeignClient("users")
public interface UserClient extends UserService {
}
1.5 feign请求/响应压缩
feign请求或响应开启 GZIP 压缩
feign.compression.request.enabled=true
feign.compression.response.enabled=true
压缩配置:(压缩类型和最小压缩阈值)
feign.compression.request.enabled=true
feign.compression.request.mime-types=text/xml,application/xml,application/json
feign.compression.request.min-request-size=2048
对于http客户端除了OkHttpClient,默认的gzip解码器可以解码UTF-8编码gzip响应:
feign.compression.response.enabled=true
feign.compression.response.useGzipDecoder=true
1.6 feign日志
为创建的每个虚拟客户机创建一个日志程序。默认情况下,日志记录器的名称是用于创建佯装客户机的接口的完整类名。佯装日志只对调试级别作出响应。
logging.level.project.user.UserClient: DEBUG
日志记录器。级别对象,你可以配置每个客户端,告诉假装多少日志。的选择是:
NONE 没有日志记录(默认)。
BASIC,只记录请求方法和URL以及响应状态代码和执行时间。
HEADERS,记录基本信息以及请求和响应标头。
FULL,记录请求和响应的头、正文和元数据。
例子:
@Configuration
public class FooConfiguration {@BeanLogger.Level feignLoggerLevel() {return Logger.Level.FULL;}
}
1.7 feign @QueryMap支持
OpenFeign @QueryMap注释支持将pojo用作GET参数映射。不幸的是,默认的OpenFeign QueryMap注释与Spring不兼容,因为它缺少value属性。
Spring Cloud OpenFeign提供了一个等效的@SpringQueryMap注释,它用于将POJO或Map参数注释为查询参数映射。
例如,Params类定义了参数param1和param2:
// Params.java
public class Params {private String param1;private String param2;// [Getters and setters omitted for brevity]
}
通过@SpringQueryMap注释使用Params类:
@FeignClient("demo")
public interface DemoTemplate {@GetMapping(path = "/demo")String demoEndpoint(@SpringQueryMap Params params);
}
相关文章:
Spring Cloud OpenFeign
概述 Feign是一个声明式web服务客户端。可以像写接口一样定义http客户端。Feign还支持可插拔的编码器和解码器。Spring Cloud增加了对Spring MVC注释和使用Spring Web中默认使用的HttpMessageConverter的支持。Spring Cloud集成了Ribbon和Eureka,以及Spring Cloud L…...
Oracle 数据库函数的用法(一)
Oracle数据库提供了大量的内置函数,可以用于完成各种操作,如字符串操作,数学计算,日期时间处理,条件判断,序列生成,聚合统计等。以下是一些常用的Oracle数据库函数: 一、oracle 使用…...

【C2C+GRCC】Exploring Disentangled Content Information for Face Forgery Detection
文章目录 Exploring Disentangled Content Information for Face Forgery Detection背景key points研究贡献方法增强解纠缠特性的独立性实验数据内评估跨方法评估跨数据集评估消融实验总结Exploring Disentangled Content Information for Face Forgery Detection 会议/期刊:…...

springboot461学生成绩分析和弱项辅助系统设计(论文+源码)_kaic
摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装学生成绩分析和弱项辅助系统软件来发挥其高效地信息处理的作…...

Unity复刻胡闹厨房复盘 模块一 新输入系统订阅链与重绑定
本文仅作学习交流,不做任何商业用途 郑重感谢siki老师的汉化教程与代码猴的免费教程以及搬运烤肉的小伙伴 版本:Unity6 模板:3D 核心 渲染管线:URP ------------------------------…...

使用“NodeMCU”、“红外模块”实现空调控制
项目思路 空调遥控器之所以能够实现对空调的控制,是因为它能够向空调发射出特定的红外信号。从理论上来说,任何能够发射出这种相同红外信号的红外发射器,都可以充当空调遥控器(这也正是手机能够控制多种不同品牌空调的原因所在&a…...

2023年西南大学数学建模C题天气预报解题全过程文档及程序
2023年西南大学数学建模 C题 天气预报 原题再现: 天气现象与人类的生产生活、社会经济、军事活动等方方面面都密切相关,大到国家,小到个人,都受到极端天气的影响。2022年6月,全球陆地地区出现了自1850年代末人类有系…...
【大模型】使用DPO技术对大模型Qwen2.5进行微调
前言 定义 DPO(Direct Preference Optimization)即直接偏好优化算法,是一种在自然语言处理领域,特别是在训练语言模型时使用的优化策略。它的主要目的是使语言模型的输出更符合人类的偏好。 背景和原理 在传统的语言模型训练中&a…...

Maven 生命周期
文章目录 Maven 生命周期- Clean 生命周期- Build 生命周期- Site 生命周期 Maven 生命周期 Maven 有以下三个标准的生命周期: Clean 生命周期: clean:删除目标目录中的编译输出文件。这通常是在构建之前执行的,以确保项目从一个…...

网络不通该如何手动下载torch
如果遇到pip install torch2.5.0 下载不了的情况,大部分是网络的问题.可以考虑下载wheel文件在去安装 查看对应的cuda版本(举个例子:cuda为12.4,找到这个版本的 复制到服务器上下载): 有conda和pip下载的两种方式,二者选其一:如果没有安装anaconda,就直接使用pip的方式下载 如…...

基础电路的学习
1、戴维南定理 ①左边的图可简化为一个电阻+一个电压源。② ③电压源可相当于开路。将R2移到左边,R1和R2相当于并联。RR1//R2 Rx和Rt相等时,灵敏度最大,因此使Rt10K。 104电容是0.1uf。 三位数字的前两位数字为标称容量的有效数…...
对 MYSQL 架构的了解
MySQL 是一种广泛使用的关系型数据库管理系统,其架构主要包括以下几个关键部分: 一、连接层 客户端连接管理:MySQL 服务器可以同时处理多个客户端的连接请求。当客户端应用程序(如使用 Java、Python 等语言编写的程序)…...

C#中方法参数传值和传引用的情况
对于引用类型 - 传类类型的具体值时 此时传的是引用 - 单纯传类类型 此时传的是个test引用的副本,在方法内修改的是这个副本的指向 传string,集合同理,只要是指向新对象,就是引用副本在指向 对于值类型 - 传普通值类型 …...
获取显示器(主/副屏)友好名称(FriendlyName)
在开发涉及多显示器的应用程序时,获取显示器的友好名称(Friendly Name)是一个常见需求。本文将深入探讨GetMonitorFriendlyName 方法,了解其实现细节和工作原理。 方法签名 public static string GetMonitorFriendlyName(bool i…...

Apache Solr RCE(CVE-2017-12629)--vulhub
Apache Solr 远程命令执行漏洞(CVE-2017-12629) Apache Solr 是一个开源的搜索服务器。Solr 使用 Java 语言开发,主要基于 HTTP 和 Apache Lucene 实现。原理大致是文档通过Http利用XML加到一个搜索集合中。查询该集合也是通过 http收到一个…...
2.3 携程的hook实现及dlsym函数
背景知识:(排除static 情况) 一个进程中可以有相同的命名吗? -- 不能 两个进程之间可以有相同的命名吗?--可以 一个进程和另一个静态库可以有相同的命名吗?--不能 一个进程和另一个动态库之间可以有相同…...

机器学习之KNN算法
K-Nearest Neighbors (KNN) 是一种常见的机器学习算法,广泛应用于分类和回归问题。KNN是一种基于实例的学习方法,它利用训练数据集的实例来进行分类或回归预测。在KNN中,预测的结果依赖于距离度量函数计算出的最近邻实例的标签或值。下面我们…...
《全排列问题》
题目描述 按照字典序输出自然数 11 到 nn 所有不重复的排列,即 nn 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。 输入格式 一个整数 nn。 输出格式 由 1∼n1∼n 组成的所有不重复的数字序列,每行一个序列。 每个数字保留…...
pycharm 快捷键
PyCharm 是一款功能强大的集成开发环境(IDE),提供了丰富的快捷键来提高开发效率。以下是一些常用的 PyCharm 快捷键(基于 Windows/Linux 系统,Mac 系统可能略有不同): 通用快捷键 功能快捷键&a…...
若依微服务如何获取用户登录信息
文章目录 1、需求提出2、应用场景3、解决思路4、注意事项5、完整代码第一步:后端获取当前用户信息第二步:前端获取当前用户信息 5、运行结果6、总结 1、需求提出 在微服务架构中,获取当前用户的登录信息是开发常见的需求。无论是后端处理业务…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...