springcloud组件之feign组件的源码分析

1. feign概述

Feign是接口调用的,但是众所周知接口是不能创建对象的,必须有实现类。而Feign的做法类似于Mybatis中mapper接口的实现,都是利用了动态代理来给接口创建一个代理对象,创建好的代理对象完成真正的调用过程。

2. 案例入门

在这里插入图片描述

  • Eureka Server:
    在这里插入图片描述
    在这里插入图片描述
  • 服务提供者:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 服务调用者feign
    在这里插入图片描述
    复制对应的方法签名到接口中,并标识对应的注解,以便Spring框架对其进行动态代理创建代理对象:
    在这里插入图片描述
    依次启动:
    在这里插入图片描述
3. feign具体步骤

① 先给接口创建对象;
② 代理对象执行进入invoke方法;
③在invoke方法中执行远程调用;
    a. 读取注解得到要调用的远程接口,provider/info;
    b. 通过ribbon+restTemplate的负载得到一个要调用的真实服务提供者;
    c. 发起请求得到响应;

4 . Feign的内部怎么实现的
  • @EnableFeignClients注解中引入了FeignClientsRegistrar类:
    在这里插入图片描述
  • 该类中实现了ImportBeanDefinitionRegistrar,可以将需要创建的对象放在注册器里面,以便spring动态代理帮我们创建代理对象:
    在这里插入图片描述
  • 在feign中我们可以将那些接口传入FeignClientsRegistrar类的以下方法中,将@FeignClient标记的接口放在registry注册器中,spring之后帮我们创建对象:
    在这里插入图片描述
  • 上面的registerFeignClients()方法会做包扫描,得到所有@FeignClient标记的接口:
    在这里插入图片描述
  • 上面最后一行代码registerFeignClient(registry, annotationMetadata, attributes);将要创建接口的代理对象的信息放在registry里面。
  • 接下来,在ReflectiveFeign的newInstance()方法中创建对应的代理对象,可以从中看到我们熟悉的代码:
    在这里插入图片描述
  • 但是这次的InvocationHandler是已经被提前实现的静态内部类:
    在这里插入图片描述
  • InvocationHandler类中的invoke()方法是代理的关键,此处相当于我们之前动态代理中自己实现的InvocationHandler匿名类:
    在这里插入图片描述
  • return dispatch.get(method).invoke(args);是真正的执行。创建一个RequestTemplate 对象
    在这里插入图片描述
  • executeAndDecode(template);继续调用:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
5. feign源码总结
  • feign通过ReflectiveFeign的newInstance()方法中的InvocationHandler handler = factory.create(target, methodToHandler)完成代理对象的创建,可以看出feign的本质就是代理对象的调用。
  • 在ReflectiveFeign.FeignInvocationHandler是实现了JDK 的InvocationHandler
发布了85 篇原创文章 · 获赞 90 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_42512488/article/details/104387916
今日推荐