springcloud微服务架构之feign组件的源码分析

文章目录

          • 1. feign概述
          • 2. 案例入门
          • 3. feign具体步骤
          • 4 . Feign的内部怎么实现的
          • 5. feign源码总结

1. feign概述

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

2. 案例入门

springcloud微服务架构之feign组件的源码分析_第1张图片

  • Eureka Server:
    springcloud微服务架构之feign组件的源码分析_第2张图片
    springcloud微服务架构之feign组件的源码分析_第3张图片
  • 服务提供者:
    springcloud微服务架构之feign组件的源码分析_第4张图片
    springcloud微服务架构之feign组件的源码分析_第5张图片
    springcloud微服务架构之feign组件的源码分析_第6张图片
  • 服务调用者feign
    springcloud微服务架构之feign组件的源码分析_第7张图片
    复制对应的方法签名到接口中,并标识对应的注解,以便Spring框架对其进行动态代理创建代理对象:
    springcloud微服务架构之feign组件的源码分析_第8张图片
    依次启动:
    springcloud微服务架构之feign组件的源码分析_第9张图片
3. feign具体步骤

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

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

你可能感兴趣的:(#,spring框架,spring,java)