前言
书接上文,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的实现咯。