【Fegin技术专题】「原生态」打开Fegin之RPC技术的开端,你会使用原生态的Fegin吗?(上)
前提介绍
- Feign是SpringCloud中服务消费端的调用框架,通常与ribbon,hystrix等组合使用。
- 由于遗留原因,某些项目中,整个系统并不是SpringCloud项目,甚至不是Spring项目,而使用者关注的重点仅仅是简化http调用代码的编写。
- *如果采用httpclient或者okhttp这样相对较重的框架,对初学者来说编码量与学习曲线都会是一个挑战,而使用spring中RestTemplate,又没有配置化的解决方案,由此想到是否可以脱离Spring cloud,独立使用Feign。
内容简介
Feign使得 Java HTTP 客户端编写更方便。Feign 灵感来源于Retrofit、JAXRS-2.0和WebSocket。Feign最初是为了降低统一绑定Denominator到HTTP API的复杂度,不区分是否支持Restful。Feign旨在通过最少的资源和代码来实现和HTTP API的连接。通过可定制的解码器和错误处理,可以编写任意的HTTP API。
maven依赖
<dependency><groupId>com.netflix.feigngroupId><artifactId>feign-coreartifactId><version>8.18.0version>dependency><dependency><groupId>com.netflix.feigngroupId><artifactId>feign-jacksonartifactId><version>8.18.0version>dependency><dependency><groupId>io.github.lukehutchgroupId><artifactId>fast-classpath-scannerartifactId><version>2.18.1version>dependency><dependency><groupId>com.netflix.feigngroupId><artifactId>feign-jacksonartifactId><version>8.18.0version>dependency>
复制代码
定义配置类
RemoteService service = Feign.builder().options(new Options(1000, 3500)).retryer(new Retryer.Default(5000, 5000, 3)).encoder(new JacksonEncoder()).decoder(new JacksonDecoder()).target(RemoteService.class, "http://127.0.0.1:8085");
复制代码
- options方法指定连接超时时长及响应超时时长
- retryer方法指定重试策略
- target方法绑定接口与服务端地址。
- 返回类型为绑定的接口类型。
自定义接口
随机定义一个远程调用的服务接口,并且声明相关的接口参数和请求地址。
通过@RequestLine指定HTTP协议及URL地址
public class User{String userName;
}public interface RemoteService {User getOwner(User user);public User getOwner( User user,String requestToken,Long userId,String userName);
}
复制代码
服务提供者
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;public class UserController {public User list( User user) throws InterruptedException{System.out.println(user.getUsername());user.setId(100L);user.setUsername(user.getUsername().toUpperCase());return user;}
}
复制代码
调用
与调用本地方法相同的方式调用feign包装的接口,直接获取远程服务提供的返回值。
String result = service.getOwner(new User("scott"));
复制代码
原生Feign的两个问题
- 原生Feign只能一次解析一个接口,生成对应的请求代理对象,如果一个包里有多个调用接口就要多次解析非常麻烦。
- Feign生成的调用代理只是一个普通对象,该如何注册到Spring中,以便于我们可以使用@Autowired随时注入。
解决方案:
- 针对多次解析的问题,可以通过指定扫描包路径,然后对包中的类依次解析。
- 实现BeanFactoryPostProcessor接口,扩展Spring容器功能。
定义一个注解类
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;public FeignApi {String serviceUrl();
}
复制代码
生成Feign代理并注册到Spring实现类:
import feign.Feign;
import feign.Request;
import feign.Retryer;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
import io.github.lukehutch.fastclasspathscanner.scanner.ScanResult;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
import java.util.List;public class FeignClientRegister implements BeanFactoryPostProcessor{private String scanPath="com.xxx.api";public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {List classes = scan(scanPath);if(classes==null){return ;}System.out.println(classes);Feign.Builder builder = getFeignBuilder();if(classes.size()>0){for (String claz : classes) {Class targetClass = null;try {targetClass = Class.forName(claz);String url=targetClass.getAnnotation(FeignApi.class).serviceUrl();if(url.indexOf("http://")!=0){url="http://"+url;}Object target = builder.target(targetClass, url);beanFactory.registerSingleton(targetClass.getName(), target);} catch (Exception e) {throw new RuntimeException(e.getMessage());}}}}public Feign.Builder getFeignBuilder(){Feign.Builder builder = Feign.builder().encoder(new JacksonEncoder()).decoder(new JacksonDecoder()).options(new Request.Options(1000, 3500)).retryer(new Retryer.Default(5000, 5000, 3));return builder;}public List scan(String path){ScanResult result = new FastClasspathScanner(path).matchClassesWithAnnotation(FeignApi.class, (Class aClass) -> {}).scan();if(result!=null){return result.getNamesOfAllInterfaceClasses();}return null;}
}
复制代码
调用接口编写示例:
import com.xiaokong.core.base.Result;
import com.xiaokong.domain.DO.DeptRoom;
import feign.Headers;
import feign.Param;
import feign.RequestLine;
import com.xiaokong.register.FeignApi;import java.util.List;public interface RoomApi {Result selectById( String id);Result> selectList();
}
复制代码
接口使用示例:
public class ServiceImpl{private RoomApi roomApi;public void demo(){Result result = roomApi.selectById("1");System.out.println(result);}
}
复制代码
注意事项:
- 如果接口返回的是一个复杂的嵌套对象,那么一定要明确的指定泛型,因为Feign在解析复杂对象的时候,需要通过反射获取接口返回对象内部的泛型类型才能正确使用Jackson解析。如果不明确的指明类型,Jackson会将json对象转换成一个LinkedHashMap类型。
- 如果你使用的是的Spring,又需要通过http调用别人的接口,都可以使用这个工具来简化调用与解析的操作。
分享资源

获取以上资源请访问开源项目 点击跳转
相关文章:
【Fegin技术专题】「原生态」打开Fegin之RPC技术的开端,你会使用原生态的Fegin吗?(上)
前提介绍 Feign是SpringCloud中服务消费端的调用框架,通常与ribbon,hystrix等组合使用。由于遗留原因,某些项目中,整个系统并不是SpringCloud项目,甚至不是Spring项目,而使用者关注的重点仅仅是简化http调…...
React Native Vector Icons的使用
介绍 React Native Vector Icons是一个用于在React Native应用中使用矢量图标的库。它提供了许多常见的图标集,如FontAwesome、Ionicons等。 使用 首先,你需要在你的React Native项目中安装React Native Vector Icons库。可以使用以下命令进行安装&…...
Redis安装和配置(Linux)
一、安装准备 VMware虚拟机准备: https://www.vmware.com/cn/products/workstation-pro.html Centos7.0准备: https://www.centos.org/ 二、安装 安装好VMware以后,进入VMware,然后创建新的虚拟机 创建好虚拟机以后,进行安装C…...
安卓源码分析(10)Lifecycle实现组件生命周期管理
参考: https://developer.android.google.cn/topic/libraries/architecture/lifecycle?hlzh-cn#java https://developer.android.google.cn/reference/androidx/lifecycle/Lifecycle 文章目录 1、概述2、LifeCycle类3、LifecycleOwner类4、LifecycleObserver类 1、…...
IP 多播协议(IP Multicast Protocol)
IP 多播协议(IP Multicast Protocol)是一种在网络中一对多传输数据的通信方式。在传统的单播通信中,数据从一个发送方发送到一个接收方;而在多播通信中,数据可以从一个发送方传输到多个接收方,从而有效地节…...
Jmeter 配置环境变量,简明教程专享
通过给 JMeter 配置环境变量,可以快捷的打开 JMeter: 打开终端。执行 jmeter。 配置环境变量的方法如下。 Mac 和 Linux 系统 在 ~/.bashrc 中加如下内容: export JMETER_HOMEJMeter所在目录 export PATH$JAVA_HOME/bin:$PATH:.:$JMETER…...
WebService—XFire配置笔记
在学习之前,一直以为WebService就是一个工具,在两个服务器之间建立一个通信,帮我们把需要传输的数据组织成规范的XML数据并发送到目的地,实际情况也确实是这样的,不过更高级一点的是,XFire不但可以帮我们生成XML发送,而且可以在接收了xml之后还可以直接返回对象给我们用…...
【LangChain学习】基于PDF文档构建问答知识库(一)前期准备
这系列主要介绍如何使用LangChain大模型,结合ChatGPT3.5,基于PDF文档构建专属的问答知识库。 一、 环境搭建 LangChain 和 OpenAI 本身可支持 Nodejs 和 Python 两个版本,笔者后续的介绍主要用到Python版本,如果有需要Nodejs版本…...
Word(1):文章页码设置
1.需求 在文档的封皮页不设置页码,在目录页页码设置为罗马数字,在正文使用阿拉伯数字。 2.解决方法 step1: 在封皮页的最后,点击”插入“-分隔符-分节符(下一页) step2:在目录页的最后&…...
Linux MQTT智能家居(温度,湿度,环境监测,摄像头等界面布局设置)
文章目录 前言一、温度湿度曲线布局二、环境监测界面布局三、摄像头界面布局总结 前言 本篇文章来完成另外三个界面的布局设置。 这里会使用到 feiyangqingyun的一些控件库。 一、温度湿度曲线布局 TempHumtiy.h: #ifndef TEMPHUMTIY_H #define TEMPHUMTIY_H#include <…...
权衡与选择:如何巧妙管理项目需求的优先级
在项目管理领域,处理和管理需求可能是最具挑战性的环节之一。每一个项目都充满了各种需求,从业务需求到技术需求,从用户需求到系统需求。而如何有效地为这些需求排列优先级,不仅会影响项目的进度和资源分配,还会直接关…...
UGUI组件EventTrigger用法
一.Unity编辑器中EventTrigger组件用法 1.添加事件类型 2.绑定gameObject指定组件的方法 3.方法执行逻辑 public class NewBehaviourScript : MonoBehaviour {public void PointerDown(){Debug.Log("Trigger PointerDown");} } 4.按下鼠标,绑定方法成功…...
Visual Studio 2019 详细安装教程(图文版)
前言 Visual Studio 2019 安装包的下载教程、安装教程 教程 博主博客链接:https://blog.csdn.net/m0_74014525 关注博主,后期持续更新系列文章 ********文章附有百度网盘安装包链接********* 系列文章 第一篇:Visual Studio 2019 详细安装教…...
idea添加作者信息
idea添加作者信息 自定义作者信息idea添加作者信息自定义作者信息 自定义作者信息 idea添加作者信息 在idea中,经常会有这些波浪纹提示,放在上面之后会提示添加作者信息,点击添加作者信息后,但是不是自己想要的 这里提取的话好像没什么办法…...
后端开发6.权限控制模块
概述 权限控制采用springsecurity 数据库设计 用户表 DROP TABLE IF EXISTS `admin`; CREATE TABLE `admin` (`aid` int(32) NOT NULL AUTO_INCREMENT,`email` varchar(50) DEFAULT NULL,`username` varchar(50) DEFAULT NULL,`password` varchar(255) DEFAULT NULL,`phone…...
Golang原生实现JA3指纹修改,并支持Proxy代理
起因 抓取某个HTTPS网站的时候 开启charles代理能够抓取成功,关闭被风控 通过检测,怀疑可能是tls的时候有区别 尝试 golang的http中,Transport.TLSClientConfig是可以自定义设置的 但起初通过随意设置并不能绕过风控 困难 使用golang的http客户端,修改DialTLSContext函数的…...
一个案例:Vue2组件化开发组件从入门到入土
1. 环境搭建 1.1. 创建项目 npm install -g vue/clivue create vue_study_todolist1.2. 清空项目代码 清楚HelloWorld.Vue代码中的内容。 1.3. 启动空项目 1.4 项目目标 项目组件实现以下效果 2. 组件拆分代码 Vue是一个基于组件的框架,允许您将界面拆分成小的…...
智慧工地源码 智慧工地云平台源码 智慧工地APP源码
智慧工地的核心是数字化,它通过传感器、监控设备、智能终端等技术手段,实现对工地各个环节的实时数据采集和传输,如环境温度、湿度、噪音等数据信息,将数据汇集到云端进行处理和分析,生成各种报表、图表和预警信息&…...
考研408 | 【计算机网络】 网络层
导图 网络层: 路由器功能:转发&路由选择 数据平面 数据平面执行的主要功能是根据转发表进行转发,这是路由器的本地动作。 控制平面 1.传统方法/每路由器法: 2.SDN方法(Software-Defined Networking) 控制平面中的…...
postgresql|数据库|角色(用户)管理工作---授权和去权以及usage和select两种权限的区别
前言: postgresql做为一个比较复杂的关系型的重型数据库,不管是安装部署,还是后期的运行维护,都还是有比较多的细节问题需要引起关注。 例如,用户权限的合理分配,那么,什么是权限的合理分配呢…...
新手小白学习人工智能,推荐什么入门书籍和课程?适合零基础的有什么?
新手小白学习人工智能,推荐什么入门书籍和课程?适合零基础的有什么? 标签:#人工智能、#深度学习、#自然语言处理、#神经网络、#机器学习、#计算机视觉、#ai### 一、零基础必看入门书籍:侧重易懂、不枯燥### 二、零基础…...
2026年户外广告机市场:这五大厂家正悄然改变行业格局
当你在繁华的商圈、繁忙的交通枢纽,甚至是在社区门口,看到一块块高清亮丽的屏幕,正精准地推送着各类信息时,你是否想过,支撑这些“城市之眼”背后的技术力量正在经历一场深刻的变革?2026年的户外广告机市场…...
深度解析Unity IL2CPP逆向工程:Cpp2IL架构设计与技术实现
深度解析Unity IL2CPP逆向工程:Cpp2IL架构设计与技术实现 【免费下载链接】Cpp2IL Work-in-progress tool to reverse unitys IL2CPP toolchain. 项目地址: https://gitcode.com/gh_mirrors/cp/Cpp2IL Cpp2IL作为专注于Unity IL2CPP逆向工程的开源工具&#…...
收藏!程序员/小白入门大模型不踩坑,从0到1转行学习全攻略
这两年,大模型彻底打破了实验室的壁垒,从高冷的技术研究,走进了每一位程序员、学生、转行者的日常工作和职业规划里。打开聊天框,总能看到相关的讨论;梳理职业路径,大模型相关岗位也成了热门选择。 几乎每天…...
告别PS!用Windows自带画图搞定图片批量裁剪(附Python自动化脚本)
告别PS!用Windows自带画图搞定图片批量裁剪(附Python自动化脚本) 在图像处理领域,批量裁剪是高频需求——无论是电商产品图统一尺寸、科研论文插图标准化,还是社交媒体内容适配多平台规格。传统方案依赖Photoshop等专业…...
Nomic-Embed-Text-V2-MoE快速上手:Python安装与环境配置全攻略
Nomic-Embed-Text-V2-MoE快速上手:Python安装与环境配置全攻略 你是不是也对最近火热的文本嵌入模型感兴趣,想亲手试试那个号称性能很强的Nomic-Embed-Text-V2-MoE?但一看到要配置Python环境、安装各种库,就觉得头大,…...
Jenkins自动化部署:如何安全存储和使用npm的authToken(附最佳实践)
Jenkins自动化部署中npm authToken的安全管理实践 在持续集成与持续交付(CI/CD)的现代开发流程中,npm作为前端生态的核心包管理工具,其认证机制的安全管理已成为DevOps工程师必须掌握的关键技能。传统交互式登录方式在自动化环境中显得笨拙且脆弱&#…...
2026深度实测:ChatGPT功能全不全?全球标杆的能力边界与本土化真相
2026年AI大模型赛道已进入成熟期,百度SEO与GEO优化成为技术内容核心流量入口,“ChatGPT功能全不全”“ChatGPT国内实用价值”“ChatGPT优缺点对比”长期占据热榜前列。作为OpenAI推出的行业标杆产品,ChatGPT历经GPT-4到GPT-5.4的迭代,从单一对话助手进化为集多模态、智能体…...
Janus-Pro-7B GPU算力优化:梯度检查点+FlashAttention-2显存节省35%
Janus-Pro-7B GPU算力优化:梯度检查点FlashAttention-2显存节省35% 1. 引言:大模型显存优化的迫切需求 Janus-Pro-7B作为DeepSeek推出的统一多模态模型,在图像理解与生成任务上表现出色,但其7B参数的规模对GPU显存提出了极高要求…...
求二维数组行优先和列优先的顺序存储的数组元素A[i][j] 的存储地址公式
行优先通用公式:列优先通用公式:数组定义:行数 列数 每个元素占 L 字节注意:以下特例的解法,通用公式仍然可以解决,只要把改成0或改成0即可。如果出现(特例和通用例子同时出现&…...
