🧭 一、初始化阶段(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.ReflectiveFeign | newInstance(Target target, Map<Method, MethodHandler> dispatch) | 创建 JDK 动态代理的核心方法 |
feign.ParseHandlersByName | apply(Target target, C requestContext) | 解析接口方法并创建 MethodHandler |
feign.MethodHandler.Factory | create(Target target, MethodMetadata md, C requestContext) | 创建 MethodHandler 的工厂接口 |
feign.SynchronousMethodHandler | invoke(...) | 同步调用实现 |
feign.AsyncMethodHandler | invoke(...) | 异步调用实现 |
org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient | execute(...) | 负载均衡调用 |
feign.Client | execute(...) | HTTP 客户端发送请求 |
✅ 总结一句话:
Feign 的调用链路由四个主要阶段组成:Feign 客户端注册 → 动态代理创建 → 本地方法拦截 → MethodHandler 执行远程调用。它通过
MethodHandler工厂机制自动适配同步、异步、Kotlin 协程等多种调用方式,并结合服务发现、HTTP 客户端、编解码器等组件完成完整的远程调用流程。