1.【SpringCloud原理】OpenFeign之FeignClient动态代理生成原理
2.SpringCloud 微服务接口调用组件 - OpenFeign 简介
3.SpringCloud原理OpenFeign原来是这么基于Ribbon来实现负载均衡的
4.SpringCloud远程调用客户端之Feign源码剖析
5.10000字 | 深入理解 OpenFeign 的架构原理
6.Spring Cloud OpenFeign源码FeignClientFactoryBean原理
【SpringCloud原理】OpenFeign之FeignClient动态代理生成原理
在SpringCloud框架中,OpenFeign组件提供了基于Java接口的HTTP客户端实现。本文将深入剖析OpenFeign中的FeignClient动态代理生成原理,从@EnableFeignClinets注解的作用、Feign客户端接口动态代理的生成源码剖析以及Feign动态代理构造过程总结三方面进行详细阐述。
首先,源码库我们来分析@EnableFeignClinets注解的作用。这个注解实际上是整个Feign组件的入口,通过@Import注解导入FeignClientsRegistrar类,该类实现了ImportBeanDefinitionRegistrar接口,当Spring Boot启动时,会调用该类的registerBeanDefinitions方法动态注入bean到Spring容器中。其中,registerFeignClients方法负责扫描带有@FeignClient注解的类,并生成对应的BeanDefinition。
在Feign客户端接口动态代理的生成源码剖析部分,我们主要关注FeignAutoConfiguration和FeignClientsConfiguration配置类。FeignAutoConfiguration是Feign在整个SpringCloud中的配置类,其中会注入一系列FeignClientSpecification对象,并将其封装到FeignContext中,最后将FeignContext注入到Spring容器中。FeignContext是进行配置隔离的关键组件,它内部维护了每个客户端对应的AnnotationConfigApplicationContext、配置类的封装以及父容器等信息。通过这种方法,每个客户端的配置能够在独立的ApplicationContext中进行解析,实现了配置的隔离。
接着,我们深入解析NamedContextFactory的作用,它用于进行配置隔离,确保Ribbon和Feign的配置能够被独立管理。通过构建独立的ApplicationContext,每个客户端的配置能够在自己的上下文中进行解析,避免了配置冲突。此外,我们还会剖析FeignClientsConfiguration,这是一个默认配置类,其中包含了生成Feign客户端动态代理所需的各种bean,如解析SpringMVC注解的茶叶源码能力、构建动态代理的类等。
在构建动态代理的过程中,整个流程涉及多个关键步骤:扫描并生成BeanDefinition、注入FeignClientFactoryBean、获取代理对象等。具体而言,当@EnableFeignClinets注解生效时,会扫描所有带有@FeignClient注解的接口并生成对应的BeanDefinition。随后,通过FeignClientFactoryBean重新生成一个bean定义,注册到Spring容器中。当需要获取代理对象时,通过FeignClientFactoryBean的getObject方法调用getTarget(),进一步获取到代理对象。整个过程涉及Feign.Builder的配置、组件的获取以及最终通过Feign.Builder构建动态代理对象。
综上所述,OpenFeign在SpringCloud框架中的实现,通过一系列的注解、配置类以及组件的协作,实现了基于Java接口的HTTP客户端的动态代理生成。从@EnableFeignClinets的注解作用到Feign客户端接口的动态代理生成,再到Feign动态代理的构造过程,整个流程设计精巧,有效提高了服务间的互操作性和可维护性。对于希望深入理解OpenFeign原理的开发者而言,本文提供的分析和总结将有助于更好地掌握这一技术。
最后,尽管本文已经详细阐述了OpenFeign的动态代理生成原理,但对于Feign与Ribbon的整合以及其他SpringCloud组件的原理,未来将会有更多深入分析的文章。通过本文的总结,希望能为读者提供一个清晰的视角,以便在实际项目中灵活运用OpenFeign实现高效、稳定的远程调用。
SpringCloud 微服务接口调用组件 - OpenFeign 简介
本文是SpringCloud专栏的开篇之作,将逐步分享在实际工作中运用到的微服务组件及填坑经验,以期对大家有所帮助,迪士尼源码减少踩坑的次数。
专栏所采用的版本为SpringCloud .0.5及SpringBoot 2.5.0。
OpenFeign是声明式的Rest接口客户端,相当于HttpClient,用于实现服务接口的远程调用。假设集群中有服务A和B,通过OpenFeign注解,服务A可以自动调用服务B的远程Rest接口,如同调用本地方法。
示例代码中,通过Spring中获取Bean并调用getReviewerIds方法,即可请求远程服务AUTH的Rest接口。
具体实例可参考官网提供的Feign Using Eureka示例。
采用OpenFeign的原因在于它封装了Feign与RestTemplate,支持SpringMVC注解与消息转换器,结合SpringMVC定义的Controller注解,如@GetMapping、@PathVariable等,唯一区别在于当以Get方式传递Pojo对象时,提供了新的注解@SpringQueryMap。
在SpringCloud .x版本中,已移除了ribbon的负载均衡功能,改为使用SpringCloud-LoadBalance实现。
@FeignClient配置简介,其源码显示默认配置为FeignClientsConfiguration。配置方式一中,@FeignClient注解的configuration属性默认值为FeignClientsConfiguration,实际是通过@ConditionalOnMissingBean定义相关Bean。自定义配置类无需添加@Configuration注解,以免影响全局应用。
配置方式二允许在配置文件中进行设置,配置文件优先级高于配置类,同时设置@FeignClient的configuration和配置文件时,配置文件优先。
OpenFeign实现原理基于代理机制,通过自定义接口方法实现远程服务调用,且通过注册中心存储服务提供者信息,如集群数、活码源码实例IP和端口等。
@FeignClient接口推荐在消费端实现,以便于维护和避免代码冗余。然而,不同的观点倾向于将此类放置在服务端。对于引入OpenFeign带来的问题,学习研究新组件和分布式事务问题成为首要挑战。
OpenFeign使用简单,后续文章将探讨生产环境中使用OpenFeign遇到的问题及解决方案。
SpringCloud原理OpenFeign原来是这么基于Ribbon来实现负载均衡的
大家好,本文将深入探讨 SpringCloud 组件原理,特别是 OpenFeign 如何基于 Ribbon 实现负载均衡的机制。在此前的文章中,我们已详细解析了 OpenFeign 动态代理生成原理及 Ribbon 运行机制,如需回顾相关知识,欢迎关注微信公众号 “三友的java日记”,通过菜单栏查看整理内容。接下来,我们将进一步揭示 OpenFeign 与 Ribbon 如何协同工作,实现高效负载均衡。一、Feign 动态代理调用实现 rpc 流程分析
通过了解 Feign 客户端接口的动态代理生成原理,我们得知动态代理基于 JDK 的机制实现,所有方法调用最终通过 InvocationHandler 接口的 ReflectiveFeign.FeignInvocationHandler 实现。接下来,我们将探讨 FeignInvocationHandler 如何执行 rpc 调用。 FeignInvocationHandler 中的 invoke 方法实现关键步骤如下:前几行判断方法是否为 equals、hashCode、toString 等不需要走 rpc 调用的特殊方法。
从 dispatch 获取对应方法的 MethodHandler,然后调用 MethodHandler 的 invoke 方法。MethodHandler 的生成发生在构建动态代理时。
MethodHandler 是接口的实现类,分为 DefaultMethodHandler(处理接口默认方法)和 SynchronousMethodHandler(实现 rpc 调用)。我们接下来关注 SynchronousMethodHandler 中的 invoke 方法实现。 SynchronousMethodHandler 的 invoke 方法包含关键步骤:构建 RequestTemplate,用于封装构建 HTTP 请求所需的参数,如头信息和 body 等。外卖app源码
调用 findOptions(argv) 方法获取连接超时时间和读超时时间配置。如果没有配置,将使用构建 SynchronousMethodHandler 时传入的参数。
执行重试组件(通常不设置重试逻辑)。
执行 executeAndDecode(template, options),进入此方法后执行 targetRequest,遍历所有请求拦截器(Feign 的扩展点),允许在发送请求前进行参数调整,如添加请求头,这在微服务间鉴权时常用。
之后,构造请求并调用 Client 接口的 execute 方法发送请求,接收响应,并将响应数据封装为所需参数返回给调用方。二、LoadBalancerFeignClient
在理解整个动态代理调用流程后,我们发现关键在于 Client 接口的实现,负责发送 HTTP 请求。那么,Client 是什么?在关于 OpenFeign 动态代理生成的文章中,我们探讨了 Feign 在构建动态代理时填充组件到 Feign.Builder 的过程,其中包含 Client 的实现,但并未在 FeignClientsConfiguration 配置类中找到 Client 对象的声明。这提示我们,Client 实现依赖于负载均衡,是 Feign 整合 Ribbon 的入口。 接下来,我们将聚焦于 Client 的实现,特别是 Feign 如何利用 Ribbon 实现负载均衡。 首先,我们查看 Feign 与 Ribbon 整合的配置类,该类导入了关键配置类。其中,DefaultFeignLoadBalancedConfiguration 配置类声明了 LoadBalancerFeignClient 到 Spring 容器中,传入了 Client 实现、CachingSpringLoadBalancerFactory 和 SpringClientFactory。 LoadBalancerFeignClient 实现了 Client 接口,构建 Feign.Builder 时注入的是这个对象。接下来,我们深入分析构造 LoadBalancerFeignClient 的实现流程。 动态代理调用过程中得出结论,最终会调用 Client 接口的 execute 方法,因此,我们关注 execute 方法的实现。此方法包含一系列操作,从请求 URL 中获取 clientName(服务名),并利用 OpenFeign 构建动态代理时传入的 HardCodedTarget 从 URL 中提取服务名。获取服务名后,LoadBalancerFeignClient 调用 lbClient 方法。 lbClient 方法实现关键步骤,首先从缓存中获取或创建 FeignLoadBalancer,然后利用 CachingSpringLoadBalancerFactory 的 create 方法构建 FeignLoadBalancer。 FeignLoadBalancer 实现关键逻辑,调用 executeWithLoadBalancer 方法处理请求,接收 Response 后直接返回。三、FeignLoadBalancer
FeignLoadBalancer 是关键组件,负责负载均衡和 HTTP 请求的发送。它继承 AbstractLoadBalancerAwareClient,实现了核心功能。 FeignLoadBalancer 的 execute 方法包含关键步骤,直接定位到核心代码行,request.client() 获取注入的 Client 实现,即 Client.Default 类或基于 HttpClient 或 OkHttp 的实现。调用此行代码成功发送 HTTP 请求,接收响应后封装成 RibbonResponse,最终返回给 MethodHandler,解析响应并封装为方法的返回值。总结
通过本文,我们完整解析了 OpenFeign、Ribbon 和 Nacos(或其他注册中心)协同工作原理,涵盖五个关键组件的源码和流程。简而言之,OpenFeign 在进行 rpc 调用时,由于服务所在机器未知,Ribbon 负责从机器列表中选择一个,该列表由注册中心提供。Ribbon 的 ServerList 接口允许注册中心实现,获取服务机器列表。通过这三个组件的协同作用,实现了微服务架构中的高效负载均衡。 本文旨在帮助读者了解微服务架构的基本原理,同时深入理解 OpenFeign、Ribbon 和 Nacos 的源码。如有疑问或交流需求,欢迎关注微信公众号 “三友的java日记” 或添加微信 ZZYNKXJH 联系作者。感谢阅读,期待与您在下篇文章中相遇。SpringCloud远程调用客户端之Feign源码剖析
Spring Cloud 的远程调用客户端 Feign 的源码解析
本文深入探讨 Spring Cloud 远程调用客户端 Feign 的源码实现。首先,我们关注 org.springframework.cloud.openfeign.EnableFeignClients 注解,其主要作用在于扫描 Feign 客户端以及配置信息,并引入 org.springframework.cloud.openfeign.FeignClientsRegistrar。这个注解所执行的操作包括两部分:扫描配置类信息和扫描客户端。
在 FeignClientsRegistrar 类中,主要通过解析 EnableFeignClients 注解的属性信息并注册默认配置来完成配置类信息的扫描。随后,它将配置类注入到 Spring 容器中,实现配置信息的注册。接着,Feign 的自动装配过程通过 FeignAutoConfiguration 类中注入的 Feign 上下文来实现,它创建了一个 Feign 实例工厂,并从 Spring 上下文中获取 Feign 实例。
在初始化阶段结束后,我们可以通过 Spring 容器获取 Feign 客户端。具体过程在 FeignClientsRegistrar#registerFeignClients 中实现,传入一个工厂到 BeanDefinition 的封装中。接着,通过工厂获取目标对象,主要过程涉及获取 Feign 上下文、利用上下文获取构造器以及调用 FeignClientFactoryBean#loadBalance 方法。
在 FeignClientFactoryBean#loadBalance 中,主要任务是使用 Feign 上下文获取客户端并设置构造器,最后获取目标并调用其 target 方法。这一过程最终指向 Feign 的核心实现,生成了一个 Feign 代理对象。
获取 Feign 代理对象后,我们可以通过调用代理对象的 invoke 方法进行远程调用。这一过程通过 feign.InvocationHandlerFactory 中的实现来完成,最终调用 Feign 实现的 executeAndDecode 方法执行实际的远程调用。整个调用过程涉及获取客户端基本信息、执行调用以及通过动态代理返回结果。
最后,Feign 调用最终通过 HTTP 协议进行远程请求的发送。整个解析过程展示了 Feign 如何通过 Spring Cloud 的集成,提供了一种优雅、灵活的远程调用方式,同时利用了 Feign 的动态代理和上下文管理,使得远程调用的实现变得更加简单、高效。
字 | 深入理解 OpenFeign 的架构原理
这是悟空的第篇原创文章 官网:passjava.cn 深入理解 OpenFeign 的架构原理,让你轻松掌握远程调用的精髓。 远程调用与本地调用相对,本地调用即在同一服务内部方法间的调用,而远程调用涉及不同服务间的调用。通过构造HTTP请求,我们能实现远程服务的调用。然而,构造请求的过程繁琐。Feign组件简化了这一过程,使得远程调用如同调用本地方法一样简单。 Feign与OpenFeign之间的关系:OpenFeign是Feign的增强版本,支持MVC注解。Spring Cloud中,OpenFeign是微服务组件的关键部分。以下是如何使用OpenFeign执行远程调用的步骤: 1. 定义远程调用接口并使用@FeignClient注解指定服务名。 2. 在启动类上添加@EnableFeignClients注解以开启远程调用功能,并开启服务发现。 3. 在远程服务定义方法,其路径与调用接口URL一致。 4. 引入OpenFeign组件与相关服务依赖。 5. 调用远程服务方法,实现数据的获取与交互。 OpenFeign的使用简洁明了,然而其内部设计复杂。本文通过分析核心流程图,详细解析了OpenFeign的工作原理,包括包扫描、注册FeignClient到Spring容器、动态代理生成、MVC注解解析、请求发送与响应处理等关键环节。通过理解这些原理,你可以轻松构建高效稳定的微服务架构。 本文以PassJava开源项目为实例,深入剖析了OpenFeign的架构设计,通过图解与源码解读,清晰地展示了OpenFeign的核心流程与工作原理。理解这些原理将帮助你更深入地掌握微服务中远程调用的实现与优化。 通过本文的学习,你将能够:掌握远程调用的概念与实现方式。
理解Feign与OpenFeign的功能与区别。
学会如何使用OpenFeign进行远程服务调用。
深入解析OpenFeign的核心流程,包括包扫描、代理生成、注解解析与请求处理。
构建基于OpenFeign的高效稳定的微服务架构。
本文为开源项目PassJava中的OpenFeign使用提供了一套全面的指南,帮助开发者深入理解其架构原理,进而提升微服务开发能力。Spring Cloud OpenFeign源码FeignClientFactoryBean原理
Spring Cloud OpenFeign的FeignClientFactoryBean在实例化过程中,通过FactoryBean接口实现,GetObject方法的关键步骤包括获取FeignContext、配置Feign.Builder、创建HardCodedTarget和调用loadBalance方法。这些步骤涉及自动配置、FeignClientSpecification的使用、Logger和Builder组件的定制以及动态代理的生成。最后,getObject方法返回的是一个接口的代理类,用于执行远程调用。
详细分析:
FeignClientFactoryBean在Spring容器中,通过getObject方法转化为实际的FeignClient实例。首先,它从FeignContext获取相关配置,这个配置在引入OpenFeign依赖时自动注入。接下来,通过getTarget方法,FeignClientFactoryBean配置了Builder组件,如Logger(非Slf4j)、RequestInterceptor、Encoder和Decoder等,同时考虑了用户自定义组件的配置。之后,创建了HardCodedTarget,基于FeignClient接口、注解值和完整URL构建,然后通过loadBalance方法,整合了LoadBalancerFeignClient和HystrixTargeter,进行负载均衡和目标URL定位。
在newInstance方法中,解析了接口方法的注解,生成了MethodHandler,并用FeignInvocationHandler封装,这个InvocationHandler在代理类实例化时被调用,实现了远程调用。最终,通过Proxy.newProxyInstance动态生成了代理类,完成FeignClientFactoryBean的实例化过程。
总的来说,FeignClientFactoryBean实例化是通过一系列配置和代理生成,实现了Spring Cloud OpenFeign的远程调用功能。如果你对源码的深入理解感兴趣,下期文章将继续解析调用源码细节。