OpenFeign原理

324 阅读2分钟

🧭 一、初始化阶段(Feign 客户端注册)

@EnableFeignClients → FeignClientsRegistrar
→ 扫描 @FeignClient 接口 → 创建 BeanDefinition
→ 注册 Feign 客户端 Bean → FeignClientFactoryBean.getObject()
→ 构建 ReflectiveFeign 实例 → Feign.build()
  • 关键类
    • FeignClientsRegistrar:负责扫描和注册 Feign 客户端;
    • FeignClientFactoryBean:创建 Feign 客户端代理对象;
    • ReflectiveFeign:默认的 Feign 客户端实现。

🧭 二、动态代理创建阶段

ReflectiveFeign.newInstance() → new Proxy.newProxyInstance(...)
→ InvocationHandler = FeignInvocationHandler
→ dispatch Map<Method, MethodHandler> 初始化
  • 关键类
    • FeignInvocationHandler:JDK 动态代理处理器;
    • ParseHandlersByName.apply():解析接口方法并生成对应的 MethodHandler
    • MethodHandler.Factory.create():根据方法签名选择合适的 MethodHandler 实现。

🧭 三、方法调用阶段(本地方法拦截处理)

proxy.methodCall(...) → FeignInvocationHandler.invoke()
→ 判断是否是 Object 方法(equals/hashCode/toString)
→ 如果不是,进入远程调用流程
  • 关键逻辑
    • 拦截 Object 类方法并本地处理;
    • 避免将这些方法作为远程调用发送出去,防止无限递归或性能浪费。

🧭 四、MethodHandler 调用阶段(远程请求执行)

dispatch.get(method).invoke(args)
→ 根据 MethodHandler 类型执行不同逻辑
→ SynchronousMethodHandler.invoke() / AsyncMethodHandler.invoke() / CoroutineMethodHandler.invoke()
→ 构造 RequestTemplate 并编码参数
→ LoadBalancerFeignClient.execute() → 获取服务实例并负载均衡
→ Client.execute() 发起真实 HTTP 请求
→ Decoder 解析响应为 Java 对象
  • 关键组件
    • Contract:解析接口方法注解;
    • Encoder/Decoder:请求参数编码与响应解码;
    • Client:HTTP 客户端(如 OkHttp、Apache HttpClient);
    • LoadBalancerFeignClient:支持服务发现与负载均衡(Ribbon/Spring Cloud LoadBalancer)。

📌 示例说明:以 CiFeignClient.textAuditing() 为例

ciFeignClient.textAuditing("敏感内容");

完整调用链如下:

proxy.ciFeignClient.textAuditing("敏感内容")
→ FeignInvocationHandler.invoke()
→ dispatch.get(method).invoke(args)
→ SynchronousMethodHandler.invoke()
→ LoadBalancerFeignClient.execute()
→ ApacheHttpClient 或 OkHttpClient 发送 POST 请求到 http://service-driver/ci/textAuditing
→ 接收响应并反序列化为 Result<TextAuditingVo>

🧠 设计模式回顾

模式应用
代理模式JDK 动态代理用于拦截接口方法调用
工厂模式MethodHandler.Factory 根据方法签名创建不同类型的处理器
策略模式不同方法绑定不同 MethodHandler 实现(同步、异步、缓存等)
模板方法模式invoke() 方法统一入口,不同分支执行不同逻辑
装饰器模式LoadBalancerFeignClient 包装原始 Client 实现负载均衡

📦 示例源码路径

类名方法描述
feign.ReflectiveFeignnewInstance(Target target, Map<Method, MethodHandler> dispatch)创建 JDK 动态代理的核心方法
feign.ParseHandlersByNameapply(Target target, C requestContext)解析接口方法并创建 MethodHandler
feign.MethodHandler.Factorycreate(Target target, MethodMetadata md, C requestContext)创建 MethodHandler 的工厂接口
feign.SynchronousMethodHandlerinvoke(...)同步调用实现
feign.AsyncMethodHandlerinvoke(...)异步调用实现
org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClientexecute(...)负载均衡调用
feign.Clientexecute(...)HTTP 客户端发送请求

✅ 总结一句话:

Feign 的调用链路由四个主要阶段组成:Feign 客户端注册 → 动态代理创建 → 本地方法拦截 → MethodHandler 执行远程调用。它通过 MethodHandler 工厂机制自动适配同步、异步、Kotlin 协程等多种调用方式,并结合服务发现、HTTP 客户端、编解码器等组件完成完整的远程调用流程。