亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring中Feign的調(diào)用流程詳解

 更新時(shí)間:2023年11月21日 09:06:00   作者:dalianpai  
這篇文章主要介紹了Spring中Feign的調(diào)用流程詳解,分析過(guò)了創(chuàng)建的代理是FeignInvocationHandler,那我們就打斷點(diǎn),停在它的反射方法上,看看到底做了什么,需要的朋友可以參考下

Feign的調(diào)用流程

動(dòng)態(tài)代理的入口

前面已經(jīng)分析過(guò)了創(chuàng)建的代理是FeignInvocationHandler,那我們就打斷點(diǎn),停在它的反射方法上,看看到底做了什么。

@Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      if ("equals".equals(method.getName())) {
        try {
          Object otherHandler =
              args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
          return equals(otherHandler);
        } catch (IllegalArgumentException e) {
          return false;
        }
      } else if ("hashCode".equals(method.getName())) {
        return hashCode();
      } else if ("toString".equals(method.getName())) {
        return toString();
      }
 
      return dispatch.get(method).invoke(args);
    }

dispatch此處就是之前封裝的5個(gè)SynchronousMethodHandler方法的集合,這里更加方法去獲取,然后調(diào)用invoke方法。來(lái)到了SynchronousMethodHandler這個(gè)方法。

@Override
  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;
      }
    }
  }

第一行首先會(huì)創(chuàng)建出一個(gè)template的,它的結(jié)果如下圖:

image-20211020111759451

最終把上面獲取到的2個(gè)變量帶到了executeAndDecode方法,這個(gè)方法才是執(zhí)行和解碼的方法。

Object executeAndDecode(RequestTemplate template, Options options) throws Throwable {
      //這里的request就已經(jīng)把服務(wù)名給加上了,變成了一個(gè)具體的請(qǐng)求。
    Request request = targetRequest(template);
 
    if (logLevel != Logger.Level.NONE) {
      logger.logRequest(metadata.configKey(), logLevel, request);
    }
 
    Response response;
    long start = System.nanoTime();
    try {
       //來(lái)到了這里,無(wú)論是負(fù)載均衡還是請(qǐng)求響應(yīng)都是這邊完成的,那我們就點(diǎn)進(jìn)去看看。
      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;
    }
  }

image-20211020134735701

image-20211019163335889

Feign是如何實(shí)現(xiàn)負(fù)載均衡的

image-20211019163652954

image-20211020134908197

先進(jìn)入到前面的lbClient方法,返回一個(gè)FeignLoadBalancer,說(shuō)明這里和ribbon結(jié)合了。

private FeignLoadBalancer lbClient(String clientName) {
		return this.lbClientFactory.create(clientName);
	}

此處調(diào)用了一個(gè)create方法,那就進(jìn)去看看。

image-20211019164151403

注意這里的factory,其實(shí)就是SpringClientFactory,從它里面獲取了lb,lb里面包含了注冊(cè)的服務(wù)清單,然后再把它放到本地的緩存當(dāng)中。

image-20211019164405363

接著就會(huì)執(zhí)行,現(xiàn)在它的sumbit方法中打一個(gè)斷點(diǎn):

image-20211020140024852

發(fā)現(xiàn)里面會(huì)執(zhí)行一個(gè)selectServer()方法,肯定是這個(gè)里面選擇了服務(wù)

image-20211020140146188

在點(diǎn)進(jìn)去看看,于是就找到了ribbon中熟悉的方法了,就是這里選擇了那個(gè)服務(wù)

image-20211020140513907

選擇好了那個(gè)服務(wù),就繼續(xù)放下走,開(kāi)始這邊拼接ip和url了

image-20211019164601834

會(huì)把選擇的ip和后面請(qǐng)求的url都傳進(jìn)來(lái)。

image-20211020135733168

在其父類(lèi)的reconstructURIWithServer方法中完成了拼接,如下圖:

image-20211020135847867

后面就是請(qǐng)求響應(yīng)和解碼了

到此這篇關(guān)于Spring中Feign的調(diào)用流程詳解的文章就介紹到這了,更多相關(guān)Feign的調(diào)用流程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java中BigDecimal類(lèi)的構(gòu)造詳解及使用

    java中BigDecimal類(lèi)的構(gòu)造詳解及使用

    這篇文章主要介紹了java中BigDecimal類(lèi)的構(gòu)造詳解及使用,Java在java.math包中提供的API類(lèi)BigDecimal,用來(lái)對(duì)超過(guò)16位有效位的數(shù)進(jìn)行精確的運(yùn)算,需要的朋友可以參考下
    2023-07-07
  • Mybatis-Plus樂(lè)觀(guān)鎖配置流程

    Mybatis-Plus樂(lè)觀(guān)鎖配置流程

    這篇文章主要介紹了Mybatis-Plus樂(lè)觀(guān)鎖配置使用流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作有一定的參考學(xué)習(xí)價(jià)值,感興趣的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2024-01-01
  • 最新hadoop安裝教程及hadoop的命令使用(親測(cè)可用)

    最新hadoop安裝教程及hadoop的命令使用(親測(cè)可用)

    這篇文章主要介紹了最新hadoop安裝教程(親測(cè)可用),本文主要講解了如何安裝hadoop、使用hadoop的命令及遇到的問(wèn)題解決,需要的朋友可以參考下
    2022-06-06
  • java多線(xiàn)程下載文件原理解析

    java多線(xiàn)程下載文件原理解析

    這篇文章主要為大家詳細(xì)介紹了java多線(xiàn)程下載文件原理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • Java?Redis配置Redisson的方法詳解

    Java?Redis配置Redisson的方法詳解

    這篇文章主要為大家詳細(xì)介紹了Java?Redis配置Redisson的相關(guān)資料,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定參考價(jià)值,感興趣的可以了解一下
    2022-08-08
  • Java ThreadLocal詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java ThreadLocal詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    ThreadLocal,很多地方叫做線(xiàn)程本地變量,也有些地方叫做線(xiàn)程本地存儲(chǔ),本文會(huì)詳細(xì)的介紹一下,有興趣的可以了解一下
    2017-06-06
  • 利用SpringBoot解決多個(gè)定時(shí)任務(wù)阻塞的問(wèn)題

    利用SpringBoot解決多個(gè)定時(shí)任務(wù)阻塞的問(wèn)題

    當(dāng)我們?cè)赟pring Boot應(yīng)用中使用多個(gè)定時(shí)任務(wù)時(shí),任務(wù)之間的阻塞可能是一個(gè)常見(jiàn)的問(wèn)題,這可能會(huì)因任務(wù)之間的依賴(lài)、執(zhí)行時(shí)間過(guò)長(zhǎng)或資源爭(zhēng)用等原因而發(fā)生,本文讓我們深入探討如何利用Spring Boot來(lái)解決多個(gè)定時(shí)任務(wù)阻塞的問(wèn)題,感興趣的小伙伴跟著小編一起來(lái)看看吧
    2024-01-01
  • 代碼詳解java里的“==”和“equels”區(qū)別

    代碼詳解java里的“==”和“equels”區(qū)別

    本篇文章通過(guò)實(shí)例代碼給大家詳細(xì)解釋了java里的“==”和“equels”區(qū)別,對(duì)此有興趣的朋友跟著小編一起學(xué)習(xí)下。
    2018-02-02
  • SpringCloud配置刷新原理解析

    SpringCloud配置刷新原理解析

    這篇文章主要介紹了SpringCloud之配置刷新的原理,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-05-05
  • Java Reflect如何利用反射獲取屬性上的注解

    Java Reflect如何利用反射獲取屬性上的注解

    AnnotatedElement接口是Java反射機(jī)制的一部分,用于讀取運(yùn)行中程序的注釋信息,通過(guò)getAnnotation、getAnnotations、isAnnotationPresent和getDeclaredAnnotations方法,可以訪(fǎng)問(wèn)和判斷注解,Field類(lèi)實(shí)現(xiàn)了該接口
    2024-09-09

最新評(píng)論