Spring Cloud: openFegin使用
文章目录
- 一、OpenFeign简介
- 二、Springboot集成OpenFeign
- 1、引入依赖
- 2、@EnableFeignClients注解
- (1)应用
- (2)属性解析
- 3、 @FeignClient
- (1)应用
- (2)属性解析
- (3)向Fegin客户端提供URL的几种方式
- 三、openFegin应用
- 1、使用openfegin下载文件
一、OpenFeign简介
OpenFeign 利用 Ribbon 维护了远程服务的列表信息,以实现客户端侧的负载均衡。
二、Springboot集成OpenFeign
1、引入依赖
<!--openfeign-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、@EnableFeignClients注解
(1)应用
在使用openfegin时需要再启动类上加上改注解,以启用 OpenFeign。
@SpringBootApplication
@EnableFeignClients
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
(2)属性解析
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients {String[] value() default {};String[] basePackages() default {};Class<?>[] basePackageClasses() default {};Class<?>[] defaultConfiguration() default {};Class<?>[] clients() default {};
}
- basePackages 或 value
这两个属性是等价的,用于指定扫描 Feign 客户端接口的包路径。Spring Cloud 会自动扫描这些包下的接口,并为它们创建代理实现,这些代理会实现声明的 Feign 客户端接口。
@EnableFeignClients(basePackages = "com.example.demo.client")
或
@EnableFeignClients(value = "com.example.demo.client")
- defaultConfiguration
这个属性允许你指定一个默认的配置类,该类会应用于所有 Feign 客户端,除非它们有自己特定的配置。
@EnableFeignClients(defaultConfiguration = DefaultFeignConfig.class)
- clients
这个属性允许你明确地指定哪些接口应该作为 Feign 客户端来创建。这在你不想扫描整个包,而只想为特定的接口创建 Feign 客户端时非常有用。
@EnableFeignClients(clients = {MyServiceClient.class, AnotherServiceClient.class})
- basePackageClasses
@EnableFeignClients 注解中的 basePackageClasses 属性是一个替代 basePackages 或 value 的方式,用于指定扫描 Feign 客户端接口的基准类。Spring Cloud 会扫描这些基准类所在的包及其子包,以查找标有 @FeignClient 注解的接口,并为这些接口创建代理实现。
使用 basePackageClasses 而不是直接指定包路径的好处是,它提供了类型安全的方式来定义扫描的包。你只需提供一个位于所需包中的类的 Class 对象,Spring Cloud 就会自动确定该类的包路径,并扫描该包及其子包。
下面是一个使用 basePackageClasses 的例子:
@SpringBootApplication
@EnableFeignClients(basePackageClasses = MyFeignClient.class)
public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
在这个例子中,假设 MyFeignClient 接口位于 com.example.demo.client 包中。通过指定 MyFeignClient.class 作为 basePackageClasses 的值,Spring Cloud 将扫描 com.example.demo.client 包及其所有子包,查找带有 @FeignClient 注解的接口。
这样做的好处是,即使你的包结构发生变化(例如,重命名包),只要 MyFeignClient 接口仍然位于相同的包中,你就不需要更新 @EnableFeignClients 注解。因此,它提供了一种更灵活的方式来指定扫描的包,减少了由于包路径更改而导致的维护工作量。
需要注意的是,basePackageClasses 和 basePackages/value 是互斥的,你不应该同时指定它们。你应该选择其中一种方式来定义扫描的包。通常,如果你的应用结构较为简单,直接指定包路径可能更直接。而在更复杂的场景中,使用 basePackageClasses 可能会更加灵活和易于维护。
3、 @FeignClient
(1)应用
定义一个接口,并使用 @FeignClient 注解指定远程服务的名称。
import feign.Response;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;import javax.validation.constraints.NotBlank;
import java.util.List;
@FeignClient(name = "xxx", contextId = "FileServiceAPI", path = url)
@Validated
public interface FileServiceAPI {/*** 获取文件详情接口* @param code* @return*/@GetMappingBizBaseResponse<FileInfoVo> getFileDetail(@NotBlank @RequestParam(name = "code") String code);@GetMapping("files")BizBaseResponse<List<FileInfoVo>> getFileDetails( @RequestParam(name = "codes") List<String> codes);/*** 文件下载接口* @param code*/@GetMapping("/download")Response download(@RequestParam(name = "code") String code);
(2)属性解析
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface FeignClient {// name和value属性用于标注客户端名称,也可以用${propertyKey}获取配置属性@AliasFor("name")String value() default "";// 该类的Bean名称String contextId() default "";// name和value属性用于标注客户端名称,也可以用${propertyKey}获取配置属性@AliasFor("value")String name() default "";// 弃用 被qualifiers()替代。@DeprecatedString qualifier() default "";// 模拟客户端的@Qualifiers值。如果qualifier()和qualifiers()都存在,我们将使用后者,除非qualifier()返回的数组为空或只包含空值或空白值,在这种情况下,我们将首先退回到qualifier(),如果也不存在,则使用default = contextId + "FeignClient"。String[] qualifiers() default {};// 绝对URL或可解析主机名String url() default "";// 是否应该解码404而不是抛出FeignExceptionsboolean decode404() default false;// 用于模拟客户端的自定义配置类。可以包含组成客户端部分的覆盖@Bean定义,默认配置都在FeignClientsConfiguration类中,可以指定FeignClientsConfiguration类中所有的配置Class<?>[] configuration() default {};// 指定失败回调类Class<?> fallback() default void.class;// 为指定的假客户端接口定义一个fallback工厂。fallback工厂必须生成fallback类的实例,这些实例实现了由FeignClient注释的接口。Class<?> fallbackFactory() default void.class;// 所有方法级映射使用的路径前缀String path() default "";// 是否将虚拟代理标记为主bean。默认为true。boolean primary() default true;
}
(3)向Fegin客户端提供URL的几种方式
- 使用@FeignClient注解的url属性
这是最直接的方式。你可以在@FeignClient注解中直接指定URL。这样,Feign客户端就会使用这个URL来进行请求。
@FeignClient(name = "myServiceClient", url = "http://example.com/api")
public interface MyServiceClient { // 定义你的方法
}
在上面的例子中,MyServiceClient接口将使用http://example.com/api作为请求的基础URL。没有负载均衡能力,只能定向发送。
- 使用配置文件:
你可以在应用的配置文件(如application.yml或application.properties)中设置Feign客户端的URL。然后,你可以通过@Value注解或者@ConfigurationProperties来注入这个URL到Feign客户端的配置中。
# application.yml
my-service-client: url: http://example.com/api
@FeignClient(name = "myServiceClient", configuration = MyServiceClientConfiguration.class)
public interface MyServiceClient { // 定义你的方法
} @Configuration
public class MyServiceClientConfiguration { @Value("${my-service-client.url}") private String url; @Bean public Request.Options options() { return new Request.Options(connectTimeoutMillis(), readTimeoutMillis()); } private int connectTimeoutMillis() { return 10 * 1000; } private int readTimeoutMillis() { return 60 * 1000; }
}
在这个例子中,MyServiceClientConfiguration类从配置文件中读取URL,并可能还配置了其他的Feign请求选项。没有负载均衡能力,只能定向发送,优先使用注解中的url。
- 使用服务发现
如果你的应用运行在Spring Cloud环境中,并使用了服务发现(如Eureka或Consul),那么通常不需要在Feign客户端中直接指定URL。相反,你可以通过服务名称来引用远程服务,Spring Cloud会自动解析服务名称到实际的URL。
@FeignClient(name = "my-service")
public interface MyServiceClient { // 定义你的方法
}
在这个例子中,my-service是注册在服务发现中的服务名称。当发起请求时,Spring Cloud会查询服务发现来找到my-service的实例,并使用它们的URL进行请求。
三、openFegin应用
1、使用openfegin下载文件
(1)下载文件Controler实现
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths; @RestController
public class FileDownloadController { @GetMapping("/download") public void downloadFile(HttpServletResponse response) throws IOException { // 文件路径 String filePath = "path/to/your/file.txt"; // 创建文件路径 Path path = Paths.get(filePath); Resource resource = new FileSystemResource(path); // 获取文件名 String filename = resource.getFilename(); // 设置响应头 response.reset();response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\""); // 读取文件内容并写入响应输出流 try (InputStream inputStream = Files.newInputStream(path); OutputStream outputStream = response.getOutputStream()) { byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } outputStream.flush(); } }
}
(2)openfegin配置
import feign.Response;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;import javax.validation.constraints.NotBlank;
import java.util.List;
@FeignClient(name = "xxx", contextId = "FileServiceAPI", path = url)
@Validated
public interface FileServiceAPI {/*** 文件下载接口* @param code*/@GetMapping("/download")Response download();
其中Response引用的是:feign.Response
(3)调用openfegin接口方法
public File downFileByCode() {String path = PROJECT_PATH;Response response = fileServiceAPI.download(ossFileCode);mkDirs(path);File file = new File(path);if (response.status() == 200) {try (InputStream inputStream = response.body().asInputStream();FileOutputStream outputStream = new FileOutputStream(file)) {// 将响应体中的字节写入目标文件byte[] buffer = new byte[1024];int bytesRead;while ((bytesRead = inputStream.read(buffer)) != -1) {outputStream.write(buffer, 0, bytesRead);}} catch(Exception e) {LOGGER.error(e.getMessage(), e);throw new RunTimeException(e.getMessage());}}return file;}public static String mkDirs(String filePath) {if (StringUtils.isBlank(filePath)) {throw new RuntimeException("file path is null");}if (!filePath.endsWith(File.separator)) {LOGGER.info("mkdir , file path is {}", filePath);filePath = filePath.substring(0, filePath.lastIndexOf(File.separator));}//如果目录不存在,自动创建文件夹File dir = new File(filePath);if (!dir.exists()) {dir.mkdirs();}return dir.getAbsolutePath();}
相关文章:
Spring Cloud: openFegin使用
文章目录 一、OpenFeign简介二、Springboot集成OpenFeign1、引入依赖2、EnableFeignClients注解(1)应用(2)属性解析 3、 FeignClient(1)应用(2)属性解析(3)向…...
流畅的 Python 第二版(GPT 重译)(二)
第三章:字典和集合 Python 基本上是用大量语法糖包装的字典。 Lalo Martins,早期数字游牧民和 Pythonista 我们在所有的 Python 程序中都使用字典。即使不是直接在我们的代码中,也是间接的,因为dict类型是 Python 实现的基本部分。…...
Flutter 旋转动画 线性变化的旋转动画
直接上代码 图片自己添加一张就好了 import dart:math;import package:flutter/material.dart;import package:flutter/animation.dart;void main() > runApp(MyApp()); //旋转动画 class MyApp extends StatelessWidget {overrideWidget build(BuildContext context) {re…...
【Web应用技术基础】HTML(5)——案例1:展示简历信息
样式: 代码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>展示简历信息…...
ethers.js:wallet(创建钱包,导入助记词,导入私钥)
Wallet Wallet类继承了Signer,可以使用私钥作为外部拥有帐户(EOA)的标准对交易和消息进行签名。 npm install ethers@5.4.0// 引入 import {ethers } from ethers创建新钱包 this.provider = new ethers.providers.Web3Provider(window...
面试笔记——Java集合篇
Java集合框架体系 重点:单列集合——ArrayList、LinkedList;双列集合——HashMap、ConcurrentHashMap。 List相关 数组(Array) 是一种用连续的内存空间存储相同数据类型数据的线性数据结构。 数组获取其他元素: 为什…...
在 IntelliJ IDEA 中使用 Terminal 执行 git log 命令后的退出方法
前言 IntelliJ IDEA 是一款广受欢迎的集成开发环境,它内置了强大的终端工具,使得开发者无需离开IDE就能便捷地执行各种命令行操作,包括使用 Git 进行版本控制。在 IDEA 的 Terminal 中执行 git log 命令时,由于该命令会显示项目的…...
架构整洁之道-读书总结
1 概述 1.1 关于本书 《架构整洁之道》(Clean Architecture: A Craftsman’s Guide to Software Structure and Design)是由著名的软件工程师Robert C. Martin(又称为Uncle Bob)所著。这本书提供了软件开发和架构设计的指导原则…...
蓝桥杯学习笔记(贪心)
在很久很久以前,有几个部落居住在平原上,依次编号为1到n。第之个部落的人数为 t 有一年发生了灾荒,年轻的政治家小蓝想要说服所有部落一同应对灾荒,他能通过谈判来说服部落进行联台。 每次谈判,小蓝只能邀请两个部落参…...
【无标题】如何使用 MuLogin 设置代理
如何使用 MuLogin 设置代理 使用 MuLogin 浏览器设置我们的代理,轻松管理多个社交媒体或电子商务帐户。 什么是MuLogin? MuLogin 是一款虚拟反检测浏览器,使用户能够管理多个电子商务、社交媒体和广告帐户,而无需验证码或 IP 禁…...
芒果YOLOv8改进135:主干篇GCNet,统一为全局上下文建模global context结构,即插即用,助力小目标检测,轻量化的同时精度性能涨点
该专栏完整目录链接: 芒果YOLOv8深度改进教程 芒果专栏 基于 GCNet 的改进结构,改进源码教程 | 详情如下🥇 💡本博客 改进源代码改进 适用于 YOLOv8 按步骤操作运行改进后的代码即可 即插即用 结构。博客 包括改进所需的 核心结构代码 文件 论文:https://arxiv.org/a…...
全面:vue.config.js 的完整配置
vue.config.js是Vue项目的配置文件,用于配置项目的构建、打包和开发环境等。 在Vue CLI 3.0之后,项目的配置文件从原来的build和config目录下的多个配置文件,合并成了一个vue.config.js文件。这个文件可以放在项目的根目录下,用于…...
海量数据处理项目-账号微服务注册Nacos+配置文件增加
海量数据处理项目-账号微服务注册Nacos配置文件增加 导入生成好的代码 model (为啥不放common项目,如果是确定每个服务都用到的依赖或者类才放到common项目) mapper 类接口拷贝 resource/mapper文件夹 xml脚本拷贝 controller service 不拷贝 Mybatis plus配置控制…...
DNS 服务 Unbound 部署最佳实践
文章目录 安装unbound-control配置启动服务测试 参考: 官网地址:https://nlnetlabs.nl/projects/unbound/about/ 详细文档:https://unbound.docs.nlnetlabs.nl/en/latest/index.html DNS服务Unbound部署于使用 https://cloud.tencent.com/…...
力扣HOT100 - 42. 接雨水
解题思路: 动态规划 感觉不是很好想 class Solution {public int trap(int[] height) {int n height.length;if (n 0) return 0;int[] leftMax new int[n];leftMax[0] height[0];for (int i 1; i < n; i) {leftMax[i] Math.max(leftMax[i - 1], height[i…...
攻防世界-baby_web
题目信息 相关知识 使用bp进行抓包 解题过程 题目界面如下所示: 试图找index界面: 发现又跳转到http://61.147.171.105:51201/1.php页面,因此说明61.147.171.105:51201/index.php是存在的(因为笔者试了,不存在的页面会直接报…...
数据可视化基础与应用-04-seaborn库从入门到精通01-02
总结 本系列是数据可视化基础与应用的第04篇seaborn,是seaborn从入门到精通系列第1-2篇。本系列的目的是可以完整的完成seaborn从入门到精通。主要介绍基于seaborn实现数据可视化。 参考 参考:数据可视化-seaborn seaborn从入门到精通01-seaborn介绍与load_datas…...
学习 zustand
学习 zustand https://github.com/pmndrs/zustand告别繁杂的状态管理:Zustand 的简洁之道Zustand 状态库:轻便、简洁、强大的 React 状态管理工具关于 zustand 的一些最佳实践 代码库 https://gitee.com/nian_zuo_chen/learnrect/tree/master/zustand 安…...
竞赛 opencv python 深度学习垃圾图像分类系统
0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 opencv python 深度学习垃圾分类系统 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:3分创新点:4分 这是一个较为新颖的竞…...
vsto worksheet中查找关键字【关键字】获取对应的整列 union成一个range
要在 VSTO 中的工作表中查找包含特定关键字的单元格,并将这些单元格所在列合并为一个范围,可以使用以下代码:csharp using Excel Microsoft.Office.Interop.Excel;// 在工作表中查找包含特定关键字的单元格,并返回这些单元格所在…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...
Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...
