当前位置: 首页 > news >正文

openfeign 只有接口如何创建bean的

OpenFeign 能够为纯接口创建 Spring Bean,其核心机制是通过动态代理Spring 的 FactoryBean 机制实现的。以下是详细的工作原理:


1. @EnableFeignClients 注解的启动

在 Spring Boot 主类上添加 @EnableFeignClients 注解:

@SpringBootApplication
@EnableFeignClients
public class Application { ... }

此注解会触发以下操作:

  • 扫描所有被 @FeignClient 标记的接口。

  • 为每个接口注册一个特殊的 FeignClientFactoryBean


2. FeignClientFactoryBean 的作用

FeignClientFactoryBean 实现了 Spring 的 FactoryBean 接口,核心方法是 getObject()

public class FeignClientFactoryBean implements FactoryBean<Object> {@Overridepublic Object getObject() {return getTarget(); // 创建动态代理}private <T> T getTarget() {// 1. 构建 Feign 客户端Feign.Builder builder = feign(context);// 2. 生成动态代理return (T) targeter.target(this, builder, context, new HardCodedTarget<>(type, name, url));}
}

3. 动态代理的创建过程

当 Spring 容器需要注入 Feign 客户端时,会调用 getObject() 方法:

(1) 构建 Feign 实例
  • 解析接口上的注解(如 @RequestMapping, @GetMapping)。

  • 配置编码器/解码器(如 JSON 转换)。

  • 集成负载均衡(如 Ribbon)或服务发现(如 Eureka)。

(2) 生成代理对象

通过 ReflectiveFeign 创建 JDK 动态代理:

public class ReflectiveFeign extends Feign {public <T> T newInstance(Target<T> target) {// 为每个方法创建 MethodHandlerMap<Method, MethodHandler> methodHandlers = ...;// 生成代理InvocationHandler handler = new FeignInvocationHandler(target, methodHandlers);return (T) Proxy.newProxyInstance(target.type().getClassLoader(),new Class<?>[] {target.type()},handler);}
}

4. 代理的执行逻辑

当调用接口方法时,动态代理拦截请求:

class FeignInvocationHandler implements InvocationHandler {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) {// 1. 解析方法注解和参数RequestTemplate template = buildTemplateFromArgs(method, args);// 2. 发送 HTTP 请求Response response = client.execute(template, options);// 3. 解码响应return decoder.decode(response, method.getReturnType());}
}

5. Spring Bean 的注册

  • Bean 类型:代理对象(实现原始接口的 JDK Proxy)。

  • Bean 名称:默认取接口全限定名,或通过 @FeignClient(name="serviceName") 指定。

  • 依赖注入:通过 @Autowired 注入时,实际注入的是动态代理对象:

  • @Autowired
    private UserServiceClient userService; // 实际为 Proxy 实例

    关键组件总结

    组件作用
    @EnableFeignClients启动 Feign 扫描和动态代理生成
    FeignClientFactoryBeanSpring 的 FactoryBean,负责创建代理
    ReflectiveFeign生成 JDK 动态代理
    FeignInvocationHandler代理逻辑:解析注解 → 构造请求 → 发送 HTTP 调用
    LoadBalancerFeignClient集成负载均衡(如 Ribbon)

    补充说明

  • 无实现类的原理
    动态代理在运行时生成接口的实现类($Proxy0),无需手动编写实现代码。

  • HTTP 请求的发送
    底层使用可插拔的 HTTP 客户端(默认 HttpURLConnection,可替换为 OkHttp 或 Apache HttpClient)。

  • 与 Spring 的整合
    通过 FeignContext 维护独立的配置上下文(如编解码器、拦截器)。

  • sequenceDiagramparticipant Springparticipant FeignFactoryparticipant DynamicProxyparticipant HTTP_ClientSpring->>FeignFactory: 需要注入 UserServiceClientFeignFactory->>DynamicProxy: 创建代理对象DynamicProxy-->>Spring: 返回 Proxy 实例Spring->>Service: 注入 ProxyService->>DynamicProxy: 调用 userService.getUser()DynamicProxy->>HTTP_Client: 构造 HTTP 请求HTTP_Client->>Remote: 发送 GET /userRemote-->>HTTP_Client: 返回 JSON 数据HTTP_Client->>DynamicProxy: 响应结果DynamicProxy->>Service: 返回 User 对象

    通过这种设计,OpenFeign 实现了声明式 HTTP 客户端:开发者只需定义接口,框架自动处理 HTTP 通信、负载均衡和序列化。

http://www.xdnf.cn/news/1324531.html

相关文章:

  • Linux设备树简介
  • vue3入门-v-model、ref和reactive讲解
  • Leetcode 16 java
  • Effective C++ 条款49:了解new-handler的行为
  • 力扣 hot100 Day77
  • 单片机驱动LCD显示模块LM6029BCW
  • 机器翻译论文阅读方法:顶会(ACL、EMNLP)论文解析技巧
  • STM32学习笔记14-I2C硬件控制
  • 大数据计算引擎(四)—— Impala
  • Fluss:颠覆Kafka的面向分析的实时流存储
  • GPT-5之后:当大模型更新不再是唯一焦点
  • 深度学习必然用到的概率知识
  • Vue 3中watch的返回值:解锁监听的隐藏技巧
  • 敏感数据加密平台设计实战:如何为你的系统打造安全“保险柜”
  • 遥感机器学习入门实战教程 | Sklearn 案例②:PCA + k-NN 分类与评估
  • Day8--滑动窗口与双指针--1004. 最大连续1的个数 III,1658. 将 x 减到 0 的最小操作数,3641. 最长半重复子数组
  • 具身智能2硬件架构(人形机器人)摘自Openloong社区
  • Next.js 中的 SEO:搜索引擎优化最佳实践
  • flutter项目适配鸿蒙
  • JMeter与大模型融合应用之构建AI智能体:评审性能测试脚本
  • 【Jenkins】03 - 自动构建和docker构建
  • MCP协议演进:从SSE到Streamable HTTP的技术革命
  • 宁波市第八届网络安全大赛初赛(REVERSE-Writeup)
  • FPGA-Vivado2017.4-建立AXI4用于单片机与FPGA之间数据互通
  • OpenTelemetry、Jaeger 与 Zipkin:分布式链路追踪方案对比与实践
  • vscode wsl解决需要用别的用户调试的问题
  • VSCode REST Client 使用总结
  • Linux下的软件编程——IPC机制
  • Linx--MySQL--安装笔记详细步骤!
  • k8sday10服务发现(1/2)