Spring Cloud Open Feign源码分析

Open Feign(伪声明式RPC) 之所以称之为伪RPC,是因为它几乎和PRC的调用过程一样,像序列化,反序列化,动态代理之类的流程都有
面向接口的一种代理的封装,

思考Feign要做到的事情

  • 参数的解析与装载
  • 针对制定的feignClient,生成动态代理
  • 针对FeignClient中的方法描述进行解析
  • 组装出一个Request对象,发起请求

在这里插入图片描述

  • 首先从@EnableFeignClients()注解进入@Import({FeignClientsRegistrar.class});
  • FeignClientsRegistrar类实现了ImportBeanDefinitionRegistrar接口;动态的将Bean装载到IOC容器中;
  • FeignClientsRegistrar类调用registerFeignClients();对于配置的package中可以能有多个FeignClient,用双重循环遍历不同路径下的不同的FeignClients和配置;
  • 接着进入registerFeignClient()方法中;FeignClient被动态注册成一个FactoryBean
  • FactoryBean有一个特征,就是如果需要获得这个Bean的真正实例,会通过FeignClientFactoryBean.getObject()中getTarget来获取最终实例,getTarget中会根据是否有URL,如果没有执行LoadBalancer负载均衡,否则进入下一个流程。
  • 进入LoadBalancer方法的解析,其中有三个参数,FeignContext是代表Feign的上下文信息,
    protected <T> T loadBalance(Builder builder, FeignContext context, HardCodedTarget<T> target) {
        Client client = (Client)this.getOptional(context, Client.class);   //获取特定的实例的客户端
        if (client != null) {
            builder.client(client); //增加了请求的负载均衡的解析机制
            Targeter targeter = (Targeter)this.get(context, Targeter.class);
            return targeter.target(this, builder, context, target);  //target会有多种实现

        } else {
            throw new IllegalStateException("No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-netflix-ribbon?");
        }
    }

target有多种实现?
在这里插入图片描述

FeignAutoConfiguration自动装配类,自动装载FeignAutoConfigure.
在这里插入图片描述
Builder:
在这里插入图片描述
在这里插入图片描述
Client client = (Client)this.getOptional(context, Client.class);
getOptional通过获取FeignContext.getInstance(this.contextId, type); 针对某一个特定实例的上下文
在这里插入图片描述

builder.client(client);

总结:@EnableFeignClients的时候,它会扫描指定路径下FeignClient注解声明的接口,生成动态代理的类,调用GetObject的时候最终会调用getTarget完成调用。

隔离上下文 NamedContextFactory中存储contexts;通过contextID(String)来得到AnnotationConfigApplicationContext,现在子容器中找,如果找不到再去父容器中找
在这里插入图片描述
在这里插入图片描述
总结:
在这里插入图片描述
在这里插入图片描述

Feign里边 发起请求,通过动态代理(FeignClientInvocationHandler),动态代理过程中有一个很重要的部分就是Contract(默认用的是SpringMVCContract,它会对我们请求的数据FeignClient模板进行解析),之后会得到一个MethodHandler,那么分发之前会做一个encorder序列化,将对象转换为成JSON格式,序列化之后通过Request发起请求,发起请求之前LoadBalancerFeignClient做负载均衡,可以通过logger进行日志记录,接着重试机制,如果发送失败,重新发送,接着发起HTTP请求;接着Response回应,反序列化。
在这里插入图片描述

在这里插入图片描述
总体:
Robbin的两种方式

  • @LoadBalancer
  • LoadBalancerClient
    都是对RestTemplate进行操作

Robbin对得到的alllist和uplist进行负载均衡,根据IRule规则进行负载均衡(权重机制(区间算法)),/定时任务不断地发起模拟请求->LoadBalancerstat,Iping(每10s判断一次目标服务的地址,如果不可用则剔除无效地址)判断是否可用, serverList(定时任务,每30s更新一次服务列表)
如何自定义负载均衡算法,自定义

Feign->http通信:
让开发人员远程通信更加简单,对请求进行模板化开发,已经集成Robbin的使用。

对于Feign是如何扫描的,FeignClientRegister,对于每一个FeignClient注册一个工厂FeignClientFactoryBean;工厂Bean里边返回的是基于工厂bean的特性,生成动态代理类FeignInvokeHandler,使用JDK动态代理根据接口实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值