ReflectiveFeign
- 从
Feign
的使用方法我们可以推测,它的内部实现是利用了Java反射解析Api
方法上的参数与注解,生成代理实现类。所以Feign
的实现类名称就叫作ReflectiveFeign
。
/**
* ReflectiveFeign.newInstance 生成proxy代理实现的主逻辑
* @param Target<T> 在Feign.target中传入的代理目标Class与host url参数
*/
public <T> T newInstance(Target<T> target) {
//核心逻辑入口,反射解析目标Class,得到MethodHandler集合
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()) {
//Object的方法(如toString之类的)就无视
if (method.getDeclaringClass() == Object.class) {
continue;
}
//Default方法处理
else if(Util.isDefault(method)) {
DefaultMethodHandler handler = new DefaultMethodHandler(method);
defaultMethodHandlers.add(handler);
methodToHandler.put(method, handler);
}
//Http请求代理方法
else {
methodToHandler.put(method, nameToHandler.get(Feign.configKey(target.type(), method)));
}
}
//主要逻辑,生成proxy,实现其中的Rest请求方法。
//InvocationHandler实现类为FeignInvocationHandler
InvocationHandler handler = factory.create(target, methodToHandler);
T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(), new Class<?>[]{target.type()}, handler);
//处理其他默认方法,绑定到Proxy上
for(DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) {
defaultMethodHandler.bindTo(proxy);
}
return proxy;
}
-
ReflectiveFeign.newInstance
主要分为两块逻辑:
1.反射解析代理目标Class
的Method
与注解,得到MethodHandler
。
2.生成Proxy
对象,绑定Proxy
的方法实现。
- 如何从代理目标
Class
中解析出要实现的HTTP
调用方法,则是整个Feign
框架的核心业务。完成这个工作的是ParseHandlersByName.apply
方法 。
- 将解析的结果绑定到
Proxy
对象,基本上按照Java
代理的标准模式处理。主要实现逻辑在FeignInvocationHandler
中。
FeignInvocationHandler
- 先从结果开始分析,
ParseHandlersByName.apply
解析出来的结果MethodHandler
是一个抽象接口:
interface MethodHandler {
Object invoke(Object[] argv) throws Throwable;
}
- 因为这个结果最后使用在代理绑定中,所以对外暴露方法只需要一个
invoke
就足够了。
-
FeignInvocationHandler
是Java
代理中java.lang.reflect.InvocationHandler
的实现类,实现了代理对象中方法需要完成的逻辑:
//FeignInvocationHandler部分代码
static class FeignInvocationHandler implements InvocationHandler {
//代理目标Class
private final Target target;
//持有前面解析出来的MethodHandler集合
private final Map<Method, MethodHandler> dispatch;
@Override
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();
}
//Rest请求方法调用,并返回结果
return dispatch.get(method).invoke(args);
}
}
-
InvocationHandler
中只有一个invoke
方法需要实现,入参是调用的方法标识与调用参数,返回结果。
-
FeignInvocationHandler
的工作就是找到要执行方法的代理MethodHandler
,调用并return
。
- 这样
FeignInvocationHandler
就可以参与到生成Proxy
的实现中去。
- 看到这里我们就可以发现,真正发生
Rest
请求调用的是在MethodHandler
的实现类SynchronousMethodHandler
中。
网友评论