当前位置: 首页 > news >正文

Spring Cloud全解析:服务调用之Feign的执行流程


文章目录

    • Feign的执行流程


Feign的执行流程

  • 首先通过@EnableFeignClients注解开启Feign功能,程序启动时开启对@FeignClient注解的扫描

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    @Import(FeignClientsRegistrar.class)
    public @interface EnableFeignClients
    
  • 当接口的方法调用时,通过动态代理SynchronousMethodHandler生成具体的RequestTemplate

    public Object invoke(Object[] argv) throws Throwable {RequestTemplate template = buildTemplateFromArgs.create(argv);Options options = findOptions(argv);Retryer retryer = this.retryer.clone();while (true) {try {return executeAndDecode(template, options);} catch (RetryableException e) {try {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 template = buildTemplateFromArgs.create(argv);
    

    在构建RequestTemplate的时候会进行参数解析,如果参数是@RequestBody的会调用Encoder的encode方法进行编码(BuildEncodedTemplateFromArgs)

    encoder.encode(body, metadata.bodyType(), mutable);
    
  • 再根据RequestTemplate生成HTTP的Request对象

  • Request对象交给Client处理,可配置HttpURLConnection、HttpClient、OkHttp等

    // 该方法首先会调用RequestInterceptor的apply方法处理请求,之后才会进行请求发送
    // 执行完之后调用Decoder的decode方法来进行解码
    return executeAndDecode(template, options);
    
  • Client被封装到LoadBalanceClient类进行负载均衡

Object executeAndDecode(RequestTemplate template, Options options) throws Throwable {// 调用RequestInterceptor的apply方法处理请求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);} 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);boolean shouldClose = true;try {if (logLevel != Logger.Level.NONE) {response =logger.logAndRebufferResponse(metadata.configKey(), logLevel, response, elapsedTime);}if (Response.class == metadata.returnType()) {if (response.body() == null) {return response;}if (response.body().length() == null ||response.body().length() > MAX_RESPONSE_BUFFER_SIZE) {shouldClose = false;return response;}// Ensure the response body is disconnectedbyte[] bodyData = Util.toByteArray(response.body().asInputStream());return response.toBuilder().body(bodyData).build();}if (response.status() >= 200 && response.status() < 300) {if (void.class == metadata.returnType()) {return null;} else {//调用Decoder的decode方法来进行解码Object result = decode(response);shouldClose = closeAfterDecode;return result;}} else if (decode404 && response.status() == 404 && void.class != metadata.returnType()) {Object result = decode(response);shouldClose = closeAfterDecode;return result;} else {// 调用ErrorDecoder进行错误解码throw errorDecoder.decode(metadata.configKey(), response);}} catch (IOException e) {if (logLevel != Logger.Level.NONE) {logger.logIOException(metadata.configKey(), logLevel, e, elapsedTime);}throw errorReading(request, response, e);} finally {if (shouldClose) {ensureClosed(response.body());}}
}

参考文献

  • Feign的执行流程

http://www.mrgr.cn/news/30817.html

相关文章:

  • 平安人寿山西分公司:践行绿色金融,开启绿色新篇章
  • Spring Boot 的生命周期
  • Note1: Linux 多进程服务器端
  • 递归探秘:从斐波那契数列到迷宫求解
  • SpringCloud篇(服务提供者/消费者)(持续更新迭代)
  • 【数据库】数据库设计
  • springboot 集成IP白名单配置
  • MATLAB画图,曲线图如何绘制美观,曲线图10种美化方法
  • 工厂工作服穿戴监测识别摄像头
  • 【笔记】2.1 半导体三极管(BJT,Bipolar Junction Transistor)
  • 线程池的状态
  • 分享一次应用LLM解决并发现问题的经历
  • Nginx 在处理大规模分布式系统时有哪些性能优化技巧?
  • 【数据结构】排序算法---基数排序
  • 玩机进阶教程-----MTK芯片机型 回读 备份 导出分区来制作线刷包 其中MT****_Android_scatter.txt的修改 分区的写入与否
  • [杨雨贤发射器]python烟花代码
  • 电磁场与电磁波-1.3方向导数与梯度 1.4通量与散度
  • DEPLOT: One-shot visual language reasoning by plot-to-table translation论文阅读
  • Qt 常用数据类型
  • 在Spring项目中,两个实用的工具(生成类与映射文件、API自动生成)
  • 干耳屎硬掏不出来怎么办?质量最好的可视挖耳勺推荐
  • 2024自学网络安全的三个必经阶段(含路线图)
  • linux 进程间通信之pthread(条件变量共享和互斥锁共享)
  • 【吊打面试官系列-MySQL面试题】LIKE 声明中的%和_是什么意思?
  • 大模型研发全揭秘:如何通过评估指标优化大模型的表现?
  • C++中模板的初级使用函数模板(刚刚接触模板概念的小白也能明白)