Spring Cloud 2.2.2 源碼之二十一Feign初始化二

大致流程圖

在這裏插入圖片描述

FeignClientFactoryBean的getObject

在這裏插入圖片描述
獲取FeignContext對象,裏面有服務名和AnnotationConfigApplicationContext的映射,可以獲取實例,然後創建Feign.Builder
在這裏插入圖片描述

feign

進行FeignLoggerFactory的創建,可以爲某個接口配置,然後可以輸出相關請求和相應信息的。然後根據上下文獲取Feign.Builder類型的實例,並設置一些屬性,最後做一些配置。
在這裏插入圖片描述

loadBalance獲取代理對象

將前面獲取到的對象注入,並創建HardCodedTarget對象,封裝了接口類型,服務名字和拼接好的URL,這個對象可以理解爲被代理對象。
在這裏插入圖片描述
內部會先創建SpringClientFactory,然後包裝成CachingSpringLoadBalancerFactory,再從上下文中獲取LoadBalancerFeignClient實例,放進Feign.Builder裏,再獲取Targeter類型的實例,是HystrixTargeter對象,好像是因爲有相關類feign.hystrix.HystrixFeign
在這裏插入圖片描述

HystrixTargeter的target

進行目標對象的代理,其實就是設置了一些屬性,最後調用Feign.Builder進行代理處理的。如果是feign.hystrix.HystrixFeign.Builder類型的話,下面就會有一些熔斷機制的設置,這個以後說吧。
在這裏插入圖片描述

Feign.Builder的target

在這裏插入圖片描述
創建一個ReflectiveFeign對象,這裏有個方法處理器的工廠,後面的方法處理器都是他創建的,也就是SynchronousMethodHandler對象,裏面封裝了很多東西,等於是個包裝類。
在這裏插入圖片描述

ReflectiveFeign的newInstance

這裏就是動態代理的地方啦,獲取目標接口類型的所有方法,封裝成SynchronousMethodHandler,然後放入方法映射裏,最後創建一個InvocationHandler的子類ReflectiveFeign.FeignInvocationHandler,封裝目標對象HardCodedTarget和方法處理器映射methodToHandler ,然後Proxy.newProxyInstance進行動態代理。

  @Override
  public <T> T newInstance(Target<T> target) {
    Map<String, MethodHandler> nameToHandler = targetToHandlersByName.apply(target);
    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;
  }

至此,動態代理對象獲取了,然後容器會繼續執行,會將Ribbon相關的配置也注入進來,因爲底層負載均衡有用Ribbon。下篇講下這麼處理請求的原理。

好了,今天就到這裏了,希望對學習理解有幫助,大神看見勿噴,僅爲自己的學習理解,能力有限,請多包涵。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章