feign的动态代理
feign的动态代理
Feign的核心思想是使用了动态代理模式,而feign的动态代理需要用到两个组件,调用处理器和方法处理器
调用处理器FeignInvocationHandler
feign默认的调用处理器是FeignInvocationHandler
static class FeignInvocationHandler implements InvocationHandler {
private final Target target;
private final Map<Method, MethodHandler> dispatch;
FeignInvocationHandler(Target target, Map<Method, MethodHandler> dispatch) {
this.target = checkNotNull(target, "target");
this.dispatch = checkNotNull(dispatch, "dispatch for %s", target);
}
@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();
}
return dispatch.get(method).invoke(args);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof FeignInvocationHandler) {
FeignInvocationHandler other = (FeignInvocationHandler) obj;
return target.equals(other.target);
}
return false;
}
@Override
public int hashCode() {
return target.hashCode();
}
@Override
public String toString() {
return target.toString();
}
}
FeignInvocationHandler根据java实例找到MethodHandler,然后转交给MethodHandler,调用MethodHandler的invoke方法完成http请求和结果响应。
dispatch map对象是远程调用结果中的方法和对应的MethodHandler的键值对,
MethodHandler方法处理器
MethodHandler是feign自定义的接口,主要功能是调用远程url,并返回结果
SynchronousMethodHandler实现了MethodHandler接口
@Override
public Object invoke(Object[] argv) throws Throwable {
RequestTemplate template = buildTemplateFromArgs.create(argv);
Retryer retryer = this.retryer.clone();
while (true) {
try {
return executeAndDecode(template);
} catch (RetryableException e) {
retryer.continueOrPropagate(e);
if (logLevel != Logger.Level.NONE) {
logger.logRetry(metadata.configKey(), logLevel);
}
continue;
}
}
}
invoke方法中先生成requestTemplate实例,然后执行executeAndDecode方法,executeAndDecode方法中主要完成封装request请求,然后通过feignClient来进行RPC调用,最后获取响应结果。
FeignClient
feignClient有很多,默认是Client.Default类,它使用JDK的HttpURLConnection发送请求,它的性能很低。ApacheHttpClient有连接池,可以复用,OKHttpClient也是一种feignclient
总结
这篇文章主要讲了feign的动态代理的两个重要的类,调用处理器和方法处理器,调用处理器用来具体方法处理器的调度,然后在方法处理器中通过执行executeAndDecode方法来完成具体的RPC的调用,并返回响应结果,最后介绍了一下feignClient的,也就是发送http请求的客户端,默认是Client.Default,但它的性能很低,除此之外还有ApacheHttpClient和OKHttpClient,这两个客户端的效率都比较高,推荐使用这两个客户端发送http请求。希望这篇文章对feign的动态代理的分析能够对你有帮助。
- 点赞
- 收藏
- 关注作者
评论(0)