交流
商城
MCN
登入
注册
首页
提问
分享
讨论
建议
公告
动态
发表新帖
发表新帖
Fegin 第6 章:SynchronousMethodHandler
分享
未结
0
1610
李延
LV6
2021-06-22
悬赏:20积分
# 作用 在第四章中我们分析知道:在spring启动时,通过Contract解析feign的各种配置,最后为每个请求创建SynchronousMethodHandler。 当我们发送请求时就是通过这个类来进行的。 # invoke 执行请求的方法 ```java @Override public Object invoke(Object[] argv) throws Throwable { //通过RequestTemplate.Factory 获取template RequestTemplate template = buildTemplateFromArgs.create(argv); // 获取Options对象,如果参数中有Options则使用参数的,如果参数里没有则使用默认的 Options options = findOptions(argv); //获取Retryer对象 Retryer retryer = this.retryer.clone(); while (true) { try { // 执行请求 return executeAndDecode(template, options); } catch (RetryableException e) { try { //异常时判断是否需要chon4试 retryer.continueOrPropagate(e); } catch (RetryableException th) { Throwable cause = th.getCause(); if (propagationPolicy == UNWRAP && cause != null) { throw cause; } else { throw th; } } if (logLevel != Logger.Level.NONE) { logger.logRetry(metadata.configKey(), logLevel); } continue; } } } ``` 这里我们看到主要有以下几点 - 获取RequestTemplate对象 - 获取Retryer对象 - 执行请求 其中请求在一个循环里,当执行成功时直接返回,如果失败则通过retryer对象判断等待时间。 我们看一下executeAndDecode方法 # executeAndDecode ```java Object executeAndDecode(RequestTemplate template, Options options) throws Throwable { Request request = targetRequest(template); if (logLevel != Logger.Level.NONE) { logger.logRequest(metadata.configKey(), logLevel, request); } Response response; long start = System.nanoTime(); try { response = client.execute(request, options); // ensure the request is set. TODO: remove in Feign 12 response = response.toBuilder() .request(request) .requestTemplate(template) .build(); } catch (IOException e) { if (logLevel != Logger.Level.NONE) { logger.logIOException(metadata.configKey(), logLevel, e, elapsedTime(start)); } throw errorExecuting(request, e); } long elapsedTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start); if (decoder != null) return decoder.decode(response, metadata.returnType()); CompletableFuture<Object> resultFuture = new CompletableFuture<>(); asyncResponseHandler.handleResponse(resultFuture, metadata.configKey(), response, metadata.returnType(), elapsedTime); try { if (!resultFuture.isDone()) throw new IllegalStateException("Response handling not done"); return resultFuture.join(); } catch (CompletionException e) { Throwable cause = e.getCause(); if (cause != null) throw cause; throw e; } } ``` 这块比较简单主要是一下几步: 1. 通过RequestTemplate获取过Request 2. 通过client发送请求 3. 通过decoder处理返回值 ## targetRequest 通过 RequestTemplate获取Request ```java Request targetRequest(RequestTemplate template) { for (RequestInterceptor interceptor : requestInterceptors) { interceptor.apply(template); } return target.apply(template); } ``` 这里我们看到除了调用template的方法,在之前还有RequestInterceptor对于请求前的拦截
回帖
消灭零回复
提交回复
热议榜
java 相关知识分享
8
好的程序员与不好的程序员
6
写给工程师的十条精进原则
5
spring boot以jar包运行配置的logback日志文件没生成
5
一步一步分析SpringBoot启动源码(一)
5
MockMvc测试
5
【吐槽向】是不是有个吐槽的板块比较好玩
4
logstash jdbc同步mysql多表数据到elasticsearch
3
IntelliJ IDEA 优质License Server
3
.gitignore忽略规则
3
SpringBoot启动源码分析
3
一步一步分析SpringBoot启动源码(三)
3
2
一步一步分析SpringBoot启动源码(二)
2
积分不够将无法发表新帖
2
官方产品
Meta-Boot - 基于MCN
MCN - 快速构建SpringBoot应用
微信扫码关注公众号