feign的动态代理

举报
周杰伦本人 发表于 2022/07/27 11:04:50 2022/07/27
【摘要】 feign的动态代理Feign的核心思想是使用了动态代理模式,而feign的动态代理需要用到两个组件,调用处理器和方法处理器 调用处理器FeignInvocationHandlerfeign默认的调用处理器是FeignInvocationHandlerstatic class FeignInvocationHandler implements InvocationHandler { ...

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的动态代理的分析能够对你有帮助。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。