Skip to content

概念卡片:OpenFeign 声明式调用

一句话机制:OpenFeign 是声明式 HTTP 客户端——你只定义一个接口 + 注解描述要调用的 HTTP API,它就用 JDK 动态代理生成实现、解析注解构造请求、编码请求体发送、解码响应体返回对象,把「远程调用」伪装成「调本地方法」。

关键代码示例

java
// 定义 Feign 客户端接口:自动扫描并注册
@FeignClient(name = "my-cloud-user")   // name = 目标服务名(配合 Nacos 解析地址)
public interface UserFeignClient {
    @GetMapping("/api/user/findUserById/{userId}")
    User findUserById(@PathVariable("userId") Long userId);
}

调用原理(5 步)

  1. 接口定义 + 注解标注@FeignClient + @GetMapping 描述目标 API。
  2. 动态代理生成Feign.builder().target() 用 JDK 动态代理创建接口代理对象,方法调用被拦截。
  3. 请求构建Contract 组件解析注解 → 得到 HTTP 方法、URL 模板、填充路径参数(如 http://my-cloud-user/api/user/findUserById/1)。
  4. 编码 + 发送Encoder 序列化请求体 → 底层客户端(默认 JDK HttpURLConnection,可换 OkHttp/HttpClient)发请求 → Decoder 反序列化响应。
  5. 异常与重试ErrorDecoder 处理不同状态码,Retryer 自动重试。

Feign vs OpenFeign

FeignOpenFeign
关系Netflix 的早期组件(已停止维护)Spring Cloud 在 Feign 基础上的增强版
增强支持 Spring MVC 注解(@GetMapping 等)、自动装配

不变量(必须成立的约束)

  • @FeignClient(name=...)name目标服务名,配合 Nacos 把服务名解析成真实地址,不写死 IP
  • Feign 是声明式调用,本质仍是 HTTP 请求(不是真正的二进制 RPC)。
  • 底层客户端可替换(默认 HttpURLConnection,生产建议 OkHttp/HttpClient)。

踩坑案例

  • 现象:调 Feign 接口报 feign.FeignException: 404 或连接超时。 原因:路径/参数不匹配,或服务名解析不到实例(没注册到 Nacos)。解决:核对注解路径与服务名,确认目标服务已注册。

常见误解

  • 以为 Feign 和 OpenFeign 是同一个东西 → OpenFeign 是 Spring Cloud 的增强版(支持 Spring MVC 注解),Feign 已停维护。
  • 以为 Feign 是 RPC → 它是「声明式 HTTP 客户端」,底层还是 HTTP。

关联

最近更新