OpenFeign 底层执行原理
OpenFeign声明的接口底层把接口解析成方法元数据,通过动态代理生成接口的代理,并基于元数据进行Rest调用。
@EnableFeignClients注解提供的包名与@FeignClient注解修饰的接口找到所有的接口,并基于这些接口构造FeignClientFactoryBean这个FactoryBean。
FactoryBean内部真正构造的对象是一个Proxy,Proxy通过Target构造出来。Target内部构造通过Feign.Builder 的build方法完成,build方法返回的是一个Feign对象。默认情况下返回是ReflectiveFeign这个Feign对象的子类。
ReflectiveFeign的newInstance方法:
/**
* creates an api binding to the {@code target}. As this invokes reflection, care should be taken
* to cache the result.
*/
@SuppressWarnings("unchecked")
@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;
}
从代码中,我们可以看到,InvocationHandler、Proxy这些JDK内置的动态代理类完成了FactoryBean的构造。
OpenFeign是声明式接口方式的Rest客户端,只需要定义接口和对应的方法以及注解,底层会自动生成动态代理,发起Rest请求并获得最终结果。
掌握好OpenFeign的原理是至关重要的,往往我们在进行工作使用过程中,会遇到关于OpenFeign的问题,如何快定位📌问题,这就要求我们熟悉OpenFeign的工作原理。