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
。下篇講下這麼處理請求的原理。
好了,今天就到這裏了,希望對學習理解有幫助,大神看見勿噴,僅爲自己的學習理解,能力有限,請多包涵。