springcloud-feign浅析

  今天继续学习feign,feign从使用上来说非常简单,就是spring的常用使用方法,开启feign功能,使用feign注解就可以了,那今天就看看怎么开启的,如何运行的。

组件分析

  既然是从@EnableFeignClients开始使用的,那就从这个注解说起,这个注解向容器导入了FeignClientsRegistrar这个组件,那就来看看这个组件。

这样看来这就是个ImportBeanDefinitionRegistrar,用来注册bean定义的,那都注册哪些bean定义呢?

细看其实现,就是扫描就是扫描特定包的被@FeignClient标注的类,然后向容器中注册FeignClientFactoryBean,看下这个bean。

这样看来,这个bean就是个FactoryBean,看到这里,处于对spring容器的了解,应该看看其如何创建bean的了。

其构建过程还是相对复杂的,因为要涉及许多其它组件,如Client(LoadBalancerFeignClient)、Targeter(DEfaultTargeter)、Contract、Encoder、Decoder、InvocationHandlerFactory、Capability等,但总体说来就是通过Feign.Builder来构建Feign,进而获取FeignClient动态代理对象的过程,下面看看具体实现类的主要实现ReflectiveFeign。

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;
  }

从这里能看出来,就是jdk动态代理的构建过程,只不过其InvocationHandler处理了一下,看其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();
      }

      return dispatch.get(method).invoke(args);
    }

也就是从dispatch,取得方法然后执行,而这个dispatch就是那个Map(methodTohandler),也就是说在feignClient哪个方法被调用的时候,就从这个map里取出对应的MethodHandler去执行,看其具体的实现SynchronousMethodHandler,就会通过客户端Client去处理请求。

总结

  这里只是简单说了下FeignClient的创建,通过FactoryBean来扩展,通过动态代理来构建代理bean,代理bean的调用处理器InvocationHandler只是到其Map中去找到具体方法处理器去执行。那简单说就是对接口(FeignClient)进行动态代理,进而实现http请求的调用处理。

附简单流程图。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&一步

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值