Feign 客户端源码解析
Feign的使用非常简单,增加如下配置之后,便可以使用Feign进行调用。非常简单是不是。主要的工作由Feign框架完成。业务代码只提供了一个Interface, 然后由Feign动态生成代理类来实现整个的调用过程。
@Configuration
public class FeignConfig { @Bean(name = "myCient")
public MyClient myClient() {
return Feign.builder().requestInterceptor(new MyRequestInterceptor()).retryer(Retryer.NEVER_RETRY).logLevel(Logger.Level.BASIC).logger(new Slf4jLogger())
.encoder(new JacksonEncoder()).decoder(new JacksonDecoder()).
errorDecoder(new MyResultDecoder()).target(MyClient.class, "serviceUrl");
}
}
框架相关代码:
Feign.java
public Feign build() {
SynchronousMethodHandler.Factory synchronousMethodHandlerFactory =
new SynchronousMethodHandler.Factory(client, retryer, requestInterceptors, logger,
logLevel, decode404);
ParseHandlersByName handlersByName =
new ParseHandlersByName(contract, options, encoder, decoder,
errorDecoder, synchronousMethodHandlerFactory);
return new ReflectiveFeign(handlersByName, invocationHandlerFactory);
}
ReflectiveFeign.java
@SuppressWarnings("unchecked")
@Override
public <T> T newInstance(Target<T> target) {
Map<String, MethodHandler> nameToHandler = targetToHandlersByName.apply(target); // 这个方法是重点,生成了代理类具体实现。具体参考SynchronousMethodHandler。
Map<Method, MethodHandler> methodToHandler = new LinkedHashMap<Method, MethodHandler>();
List<DefaultMethodHandler> defaultMethodHandlers = new LinkedList<DefaultMethodHandler>();
for (Method method : target.type().getMethods()) {
if (method.getDeclaringClass() == Object.class) {
continue;
} else if(Util.isDefault(method)) {
DefaultMethodHandler handler = new DefaultMethodHandler(method);
defaultMethodHandlers.add(handler);
methodToHandler.put(method, handler);
} else {
methodToHandler.put(method, nameToHandler.get(Feign.configKey(target.type(), method)));
}
}
InvocationHandler handler = factory.create(target, methodToHandler);
T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(), new Class<?>[]{target.type()}, handler);
for(DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) {
defaultMethodHandler.bindTo(proxy);
}
return proxy;
}
SynchronousMethodHandler.java
final class SynchronousMethodHandler implements MethodHandler{
...
//具体实现逻辑,代理类的InvokeHandler的invoke方法会调用这个方法。
@Override
public Object invoke(Object[] argv) throws Throwable {
RequestTemplate template = buildTemplateFromArgs.create(argv);
Retryer retryer = this.retryer.clone();
while (true) {
try {
return executeAndDecode(template);
} catch (RetryableException e) {
retryer.continueOrPropagate(e);
if (logLevel != Logger.Level.NONE) {
logger.logRetry(metadata.configKey(), logLevel);
}
continue;
}
}
}
...
}
Feign 客户端源码解析的更多相关文章
- FileZilla客户端源码解析
FileZilla客户端源码解析 FTP是TCP/IP协议组的协议,有指令通路和数据通路两条通道.一般来说,FTP标准命令TCP端口号是21,Port方式数据传输端口是20. FileZilla作为p ...
- Netty5客户端源码解析
Netty5客户端源码解析 今天来分析下netty5的客户端源码,示例代码如下: import io.netty.bootstrap.Bootstrap; import io.netty.channe ...
- 深入理解Feign之源码解析
转载请标明出处: 本文出自方志朋的博客 什么是Feign Feign是受到Retrofit,JAXRS-2.0和WebSocket的影响,它是一个jav的到http客户端绑定的开源项目. Feign的 ...
- Spring Cloud系列(四):Eureka源码解析之客户端
一.自动装配 1.根据自动装配原理(详见:Spring Boot系列(二):Spring Boot自动装配原理解析),找到spring-cloud-netflix-eureka-client.jar的 ...
- 第零章 dubbo源码解析目录
第一章 第一个dubbo项目 第二章 dubbo内核之spi源码解析 2.1 jdk-spi的实现原理 2.2 dubbo-spi源码解析 第三章 dubbo内核之ioc源码解析 第四章 dubb ...
- Feign源码解析
1. Feign源码解析 1.1. 启动过程 1.1.1. 流程图 1.1.2. 解释说明 Feign解析过程依赖Spring的初始化,它通过实现ImportBeanDefinitionRegistr ...
- Feign源码解析系列-那些注解们
开始 Feign在Spring Cloud体系中被整合进来作为web service客户端,使用HTTP请求远程服务时能就像调用本地方法,可见在未来一段时间内,大多数Spring Cloud架构的微服 ...
- Feign 系列(05)Spring Cloud OpenFeign 源码解析
Feign 系列(05)Spring Cloud OpenFeign 源码解析 [TOC] Spring Cloud 系列目录(https://www.cnblogs.com/binarylei/p/ ...
- Fabric1.4源码解析:客户端安装链码
看了看客户端安装链码的部分,感觉还是比较简单的,所以在这里记录一下. 还是先给出安装链码所使用的命令好了,这里就使用官方的安装链码的一个例子: #-n 指定mycc是由用户定义 ...
随机推荐
- Tokyo Tyrant(TTServer)系列(一)-介绍和安装
Tokyo Cabinet 是日本人Mikio Hirabayashi 开发的一款DBM 数据库,该数据库读写很快.哈希模式写入100 万条数据仅仅需0.643 秒.读取100 万条数据仅仅需0.77 ...
- WebViewJavascriptBridge 进行js 与native通信。
1, iOS端加载web页面.开启日志并给webView建立JS与OC的桥梁 - (void)viewWillAppear:(BOOL)animated { if (_bridge) { retur ...
- 星云STS 常用配置
STS4 下载地址:https://spring.io/tools (这个版本没有tomcat插件) STS3 下载地址:https://spring.io/tools3/sts/all ( ...
- [转]tableExport.js 导出excel 如果有负数或是空值 导出前面会自动加上单引号
原文地址:https://blog.csdn.net/private66/article/details/88718285 tableExport.js 导出excel 如果有负数或是空值 导出前 ...
- Linux零基础入门第五课
文件的基本操作(下) 文件属性 file命令 语法 >$ file file0 [file1 file2 ...] file命令用于确认文件的类型. 在Linux下,通常并不会严格按照文件扩展名 ...
- 使用JavaScript验证用户输入的是否为正整数
在项目开发中,需要使用JavaScript验证用户输入的是否为正整数. 方法一: var type="^[0-9]*[1-9][0-9]*$"; var r=new RegExp( ...
- SpringMvc自动任务调度之task实现项目源码,@Scheduled
1.Xml配置 Spring-job.xml 并在 Spring-Application.xml中Import <?xml version="1.0" encoding=&q ...
- Angular4学习笔记-目录汇总
Angular4学习笔记(一)-环境搭建 Angular4学习笔记(二)-在WebStorm中启动项目 Angular4学习笔记(三)- 路由 Angular4学习笔记(四)- 依赖注入 Angula ...
- 新书出版 |《Oracle程序员面试笔试宝典》
新书出版 |<Oracle程序员面试笔试宝典> <Oracle程序员面试笔试宝典> 丛书[数据库 面试 笔试宝典]已在京东.淘宝和天猫预售,一共 5 本,目前市场上已有4本,丛 ...
- easyui的tree节点的获取和选中
1.设置选中tree的节点 var node = $('#tt').tree('find', 1);//找到id为”tt“这个树的节点id为”1“的对象$('#tt').tree('select', ...