前言
書接上文,feign接口是如何註冊到容器想必已然清楚,現在我們着重關心一個問題,feign調用服務的時候是如何抉擇的?
一、ReflectiveFeign.FeignInvocationHandler
從上文知道feign接口調用實質上是調用的對應的動態代理接口的InvocationHandler,跟蹤源碼發現默認的InvocationHandler實現就是FeignInvocationHandler。現在我們看一下這個FeignInvocationHandler.invoke(...)方法。
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();
}
// dispath 是緩存的method 以及 method對應的MethodHandler
return dispatch.get(method).invoke(args);
}
從代碼中可以看到他是直接從緩存中拿到對應的MethodHandler,然後調用的MethodHandler的invoke方法。我們看一下MethodHandler都有哪些實現:
可以看到就兩個實現, DefaultMethodHandler處理的是feign接口中的Default修飾的方法。我們調用的遠程接口用的是SynchronousMethodHandler實現。那麼可以看到我們最終對接口的調用實際上調用的是SynchronousMethodHandler.invoke(...)方法。其實本質上是調用的Client.execute()方法,那麼我們就要看一下Client的實現咯。