SpringCloudRPC远程调用核心原理:FeignRPC动态代理实例创建流程,java反射原理面试题

本文详细介绍了Spring Cloud中Feign的RPC远程调用核心原理,包括Feign如何与Ribbon结合实现负载均衡,以及Feign客户端的动态代理实例创建过程,涉及到FactoryBean和反射机制。重点解析了FeignClientFactoryBean和Feign.Builder的角色,以及动态代理实例的创建步骤。
摘要由CSDN通过智能技术生成

在Spring Cloud微服务架构中,同一个Provider微服务一般都会运行多个实例,所以说客户端的负载均衡能力其实是必选项,而不是可选项。

生产环境下,Feign必须和Ribbon结合在一起使用,所以方法处理器MethodHandler的客户端client成员必须是具备负载均衡能力的LoadBalancerFeignClient类型,而不是完成HTTP请求提交的ApacheHttpClient等类型。只有在负载均衡计算出最佳的Provider实例之后,才能开始HTTP请求的提交。

在LoadBalancerFeignClient内部有一个delegate委托成员,其类型可能为feign.client.Default、ApacheHttpClient、OkHttpClient等,最终由该delegate客户端委托成员完成HTTP请求的提交。

至此,整体的Feign运作流程大家应该都比较熟悉了。其实,上面介绍的大致逻辑和前面介绍的模拟Feign RPC执行流程类似,只是Feign实际的运作流程的每一个环节更加细致和复杂。

RPC动态代理容器实例的FactoryBean工厂类

===========================

为了方便Feign的RPC客户端动态代理实例的使用,还需要将其注册到Spring IOC容器,以方便使用者通过@Resource或@Autoware注解将其注入其他的依赖属性。

一般情况下,Spring通过@Service等注解进行Bean实例化的配置,但是在某些情况下(比如在Bean实例化时)需要大量的配置信息,默认的Bean实例化机制是无能为力的。为此,Spring提供了一个

org.springframework.bean.factory.FactoryBean工厂接口,用户可以通过该接口在Java代码中实现定制Bean实例化的逻辑。

FactoryBean在Spring框架中占用重要的地位,Spring自身就提供了70多个FactoryBean的实现。它们隐藏了一些复杂Bean实例化的细节,给上层应用带来了便利。FactoryBean注册到容器之后,从Spring上下文通过ID或者类型获取IOC容器Bean时,获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身。

Feign的RPC客户端动态代理IOC容器实例只能通过FactoryBean方式创建,原因有两点:代理对象为通过JDK反射机制动态创建的Bean,不是直接定义的普通实现类;它配置的属性值比较多,而且是通过@FeignClient注解配置完成的。

所以,Feign提供了一个用于获取RPC容器实例的工厂类,名为FeignClientFactoryBean类。工厂类FeignClientFactoryBean的部分源码如下:

package org.springframework.cloud.openfeign;

class FeignClientFactoryBean implements FactoryBean, InitializingBean, ApplicationContextAware {

private Class<?> type; //RPC接口的class对象

private String name; //RPC接口配置的远程provider微服务名称,如demo-provider

private String url; //RPC接口配置的url值,由 @FeignClient注解负责配置

private String path; //RPC接口配置的path值,由 @FeignClient注解负责配置

private boolean decode404;

private ApplicationContext applicationContext;

private Class<?> fallback;

private Class<?> fallbackFactory;

//获取IOC容器的Feign.Builder建造者Bean

protected Builder feign(FeignContext context) {

FeignLoggerFactory loggerFactory = this.get(context, FeignLoggerFactory.class);

Logger logger = loggerFactory.create(this.type);

//从IOC容器获取Feign.Builder实例

//并且设置编码器、解码器、日志器、方法解析器

Builder builder = ((Builder)this.get(context, Builder.class))

.logger(logger)

.encoder((Encoder)this.get(context, Encoder.class))

.decoder((Deco

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值