FeignRequestInterceptor 原理详解

FeignRequestInterceptor是 OpenFeign 的请求拦截器机制,其工作原理如下:

1. 核心设计模式

责任链模式:Feign 通过拦截器链在请求发送前和接收后执行自定义逻辑。

// 拦截器接口定义 public interface RequestInterceptor { void apply(RequestTemplate template); }

2. 请求处理流程

Controller ↓ Feign Client ↓ RequestInterceptor.apply() ← 在这里修改请求 ↓ Encoder.encode() ← 序列化请求体 ↓ Client.execute() ← 发送HTTP请求 ↓ Decoder.decode() ← 反序列化响应 ↓ ResponseInterceptor ← 响应拦截器(如果存在) ↓ 返回结果

3. 拦截器工作原理

3.1 注册机制
@Configuration public class FeignConfig { // Spring会自动发现并注册所有RequestInterceptor Bean @Bean public RequestInterceptor myInterceptor() { return template -> { // 拦截逻辑 }; } }
3.2 拦截时机
// Feign内部的执行流程 public class SynchronousMethodHandler { public Object invoke(Object[] argv) { // 1. 构建请求模板 RequestTemplate template = buildTemplateFromArgs.create(argv); // 2. 应用所有拦截器 for (RequestInterceptor interceptor : requestInterceptors) { interceptor.apply(template); } // 3. 发送请求 return client.execute(template, options); } }

4. RequestTemplate 结构

public class RequestTemplate { private String method; // HTTP方法 private String url; // 请求URL private Map<String, String> headers; // 请求头 private byte[] body; // 请求体 private Map<String, String> queries; // 查询参数 // 修改header的方法 public header(String name, String... values) {} public query(String name, String... values) {} }

5. 多拦截器执行顺序

@Component @Order(1) public class AuthInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { // 1. 添加认证header template.header("Authorization", "Bearer token"); } } @Component @Order(2) public class LoggingInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { // 2. 添加日志header template.header("X-Request-Id", UUID.randomUUID().toString()); } } // 执行顺序:AuthInterceptor → LoggingInterceptor

6. 实际应用场景

场景1:传递上游请求头
@Component public class PassThroughInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { // 从当前线程获取请求上下文 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (attributes != null) { HttpServletRequest request = attributes.getRequest(); // 传递认证信息 String authHeader = request.getHeader("Authorization"); if (authHeader != null) { template.header("Authorization", authHeader); } // 传递追踪ID String traceId = request.getHeader("X-Trace-Id"); if (traceId != null) { template.header("X-Trace-Id", traceId); } } } }
场景2:添加统一header
@Component public class CommonHeaderInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { // 服务标识 template.header("X-Service-Name", "a-service"); // 调用时间戳 template.header("X-Request-Time", Instant.now().toString()); // 版本号 template.header("X-API-Version", "v1.0"); } }
场景3:请求签名
@Component public class SignInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { // 1. 获取请求参数 String method = template.method(); String url = template.url(); String body = new String(template.body()); // 2. 计算签名 String sign = calculateSign(method, url, body); // 3. 添加签名header template.header("X-Signature", sign); } }

7. 与 Spring 上下文集成

7.1 获取 Spring Bean
@Component public class TokenInterceptor implements RequestInterceptor { @Autowired private TokenService tokenService; // 可以注入其他Bean @Override public void apply(RequestTemplate template) { String token = tokenService.getToken(); template.header("Authorization", "Bearer " + token); } }
7.2 条件性拦截
@Component public class ConditionalInterceptor implements RequestInterceptor, ApplicationContextAware { private ApplicationContext context; @Override public void setApplicationContext(ApplicationContext context) { this.context = context; } @Override public void apply(RequestTemplate template) { // 根据环境决定是否添加header Environment env = context.getEnvironment(); String profile = env.getActiveProfiles()[0]; if ("prod".equals(profile)) { template.header("X-Env", "production"); } } }

8. 调试和日志

@Component @Slf4j public class LoggingInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { // 记录请求信息 log.info("Feign Request: {} {}", template.method(), template.url()); log.info("Headers: {}", template.headers()); // 添加请求ID以便追踪 String requestId = UUID.randomUUID().toString(); template.header("X-Request-ID", requestId); MDC.put("requestId", requestId); // 设置到日志上下文 } }

9. 错误处理和重试

@Component public class RetryInterceptor implements RequestInterceptor { private ThreadLocal<Integer> retryCount = new ThreadLocal<>(); @Override public void apply(RequestTemplate template) { Integer count = retryCount.get(); if (count == null) { count = 0; } // 标记重试次数 template.header("X-Retry-Count", String.valueOf(count)); retryCount.set(count + 1); } }

10. 性能考虑

@Component public class PerformanceInterceptor implements RequestInterceptor { private ThreadLocal<Long> startTime = new ThreadLocal<>(); @Override public void apply(RequestTemplate template) { startTime.set(System.currentTimeMillis()); } // 响应拦截器(Feign 6+ 支持) public void handleResponse(Response response) { Long start = startTime.get(); if (start != null) { long duration = System.currentTimeMillis() - start; log.info("Feign请求耗时: {}ms", duration); } } }

工作原理总结

  1. 自动发现:Spring 会自动发现并注册所有RequestInterceptor类型的 Bean

  2. 顺序执行:拦截器按照@Order注解顺序执行,无注解则无序

  3. 线程安全:拦截器是单例的,但每个请求都有自己的RequestTemplate

  4. 可修改性:每个拦截器都可以修改请求的所有部分(URL、header、body 等)

  5. 生命周期:拦截器在每次 Feign 调用时都会执行

  6. 上下文隔离:通过ThreadLocalRequestContextHolder实现请求级别的上下文隔离

使用建议

  1. 保持简单:拦截器逻辑应该简单,避免复杂业务逻辑

  2. 异常处理:拦截器中抛出异常会导致整个请求失败

  3. 性能注意:不要在拦截器中执行耗时操作

  4. 可测试性:设计可测试的拦截器,避免依赖静态方法

  5. 幂等性:确保拦截器的逻辑是幂等的,不会因多次执行产生副作用

通过这种拦截器机制,OpenFeign 实现了灵活的可扩展性,可以在不修改业务代码的情况下统一处理认证、日志、监控等横切关注点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1119473.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络安全保姆级入门:手把手详解五大核心技术,小白也能快速上手

网络安全技术是保护网络不受未经授权访问、破坏或盗取信息的重要手段。以下是五种零基础也能看懂的网络安全技术&#xff1a; 1.防火墙技术&#xff1a;防火墙是一种网络安全设备&#xff0c;用于监控和控制进入或离开网络的流量。它可以识别不安全的数据包&#xff0c;并阻止…

信息安全的核心支柱:深入解析网络安全技术体系与实践

一、网络安全基础 OSI参考模型与TCP/IP开放模型对比 应用层 应用层 TehnetHTTPSMTPFTP DNSTFTPSSH 表示层 会话层 传输层 传输层 TCPUDP网络层 网络层 IP协议簇&#xff08;RIP、OSPF、SNMP、ICMP&#xff09; 数据链路层 物理和数据链路层 以太网 令牌…

《深入剖析 NumPy ndarray:为何比 Python List 快 50~100 倍?》

《深入剖析 NumPy ndarray&#xff1a;为何比 Python List 快 50~100 倍&#xff1f;》 一、开篇引入&#xff1a;从 Python 到 NumPy 的速度革命 Python 以简洁优雅的语法和强大的生态系统闻名&#xff0c;从 Web 开发到数据科学、人工智能&#xff0c;它几乎无处不在。然而&…

《深度剖析 Pandas GroupBy:底层实现机制与性能瓶颈全景解析》

《深度剖析 Pandas GroupBy&#xff1a;底层实现机制与性能瓶颈全景解析》 一、开篇引入&#xff1a;从 Python 到 Pandas 的数据处理革命 Python 的简洁语法和强大生态让它成为数据科学的首选语言&#xff0c;而 Pandas 则是其中最耀眼的明星。无论是金融分析、科研数据处理&…

百考通AI:源码宝库+智能答辩,毕业季的终极“外挂”

作为一名计算机专业的学生或开发者&#xff0c;你是否经常在这样的场景中挣扎&#xff1a;毕业设计截止日期临近&#xff0c;却苦于找不到合适的项目源码作为参考&#xff1b;答辩在即&#xff0c;却要花费大量时间熬夜制作PPT。这种“白天敲代码&#xff0c;晚上做PPT”的高强…

百考通AI:源码宝库+智能答辩,毕业季的终极“外挂”

作为一名计算机专业的学生或开发者&#xff0c;你是否经常在这样的场景中挣扎&#xff1a;毕业设计截止日期临近&#xff0c;却苦于找不到合适的项目源码作为参考&#xff1b;答辩在即&#xff0c;却要花费大量时间熬夜制作PPT。这种“白天敲代码&#xff0c;晚上做PPT”的高强…

一站式办公平台 vs 单一即时通讯软件:企业该如何抉择?

在数字化转型的十字路口&#xff0c;企业管理者和IT负责人往往面临一个经典的选型难题&#xff1a; “我们是应该购买一个包罗万象的‘一站式办公平台’&#xff0c;还是选择一个专注极致沟通的‘单一即时通讯软件’&#xff1f;” 前者似乎能解决所有问题&#xff0c;但往往…

分享一个MySQL 8.0复制架构主从自动切换脚本

/* by 01022.hk - online tools website : 01022.hk/zh/formatc.html */ #!/bin/bash # # 基于GTID的MySQL 8.0 一主一从架构主从切换脚本 # 版本: 3.0 # 优化内容: 全变量配置、增强可配置性、改进错误处理 # # >>>>>>>>>>>> 第一部分&a…

告别论文问卷烦恼!百考通AI带你轻松搞定问卷设计与分析

作为一名刚经历过毕业论文“洗礼”的学长&#xff0c;我深刻理解同学们在设计问卷时的无助感。记得我当时为了设计一份像样的问卷&#xff0c;前后修改了十几遍&#xff0c;结果还被导师指出“结构混乱”、“信效度不足”。 幸运的是&#xff0c;现在有了像百考通AI这样的智能…

跨境TRO侵权是什么意思,和解最低金额是多少,如何解决,卖家必须了解的跨境TRO侵权知识

【行业预警】2025年跨境电商圈最让人揪心的事&#xff0c;莫过于TRO案件的指数级爆发&#xff01;截至2025年12月&#xff0c;全年TRO案件总量飙升至3300起&#xff0c;比2024年翻了数倍。无数卖家遭遇账户冻结、货款被扣、店铺瘫痪&#xff0c;一夜之间从盈利到“血本无归”。…

智能体工程全指南:从概念到落地,深度复盘发展现状,收藏这一篇就够了!

引言 (Introduction) 随着我们步入 2026 年&#xff0c;组织不再询问“是否”需要构建 Agent&#xff08;智能体&#xff09;&#xff0c;而是关注“如何”可靠、高效且规模化地部署它们。我们调研了 1,300 多名专业人士&#xff0c;以了解他们如何演进 AI Agent 的用例以及如何…

深度学习赋能学术写作:百考通AI如何重塑科研全流程体验

深夜的实验室&#xff0c;只有键盘敲击声与偶尔的叹息交织。屏幕上的文献密密麻麻&#xff0c;而文档里的字数增长缓慢。这可能是许多科研工作者与学生再熟悉不过的场景。 从选题的迷茫、文献的浩瀚、撰写的艰辛&#xff0c;到降重的烦恼、格式的繁琐——学术写作是一条充满挑…

TOON:一种为大模型设计的JSON压缩型数据结构

目录 TOON&#xff1a;一种为大模型设计的JSON压缩型数据结构 一、精准定义&#xff0c;什么是 TOON&#xff1f; 1、JSON 数据格式的局限性 2、TOON 的结构与优势 3、TOON 数据结构的主要特征 4、媒体类型与文件拓展名 二、举例&#xff1a;JSON 与 TOON 描述同一组数据…

AI圈炸锅!GraphRAG让大模型不再“一本正经地胡说八道“,小白程序员也能上手的知识图谱增强技术!

前言 传统RAG系统通过检索——生成两阶段法有效缓解了大模型知识陈旧和幻觉问题&#xff0c;但是在处理复杂问题仍存在局限。依赖非结构化的文本向量的检索方式&#xff0c;很难捕捉到实体之间的深层关系&#xff0c;导致上下文不精确、信息碎片化&#xff0c;甚至有发模型幻觉…

避坑!外观专利侵权判定不看百分比!3步实操法+工具实测,跨境卖家/产品人必藏

做跨境产品或工业设计的朋友&#xff0c;大概率都踩过这个坑&#xff1a;产品刚小批量量产&#xff0c;就收到平台侵权投诉&#xff1b;爆款Listing刚起量&#xff0c;TRO临时限制令直接冻结资金&#xff1b;甚至只是参考竞品改了个细节&#xff0c;就被起诉索赔——核心问题都…

开题报告智能构建:百考通AI如何重塑论文写作的起点

凌晨三点&#xff0c;实验室的灯光依旧明亮。李博士盯着屏幕上那篇修改了第八遍的开题报告&#xff0c;眼睛干涩&#xff0c;思路枯竭。文献综述部分总是被导师指出“脉络不清”&#xff0c;研究方法和实施计划需要更加具体&#xff0c;而时间表安排也不够合理。这是许多高校学…

把 Web App 装进客户端——Tauri框架实战:托盘功能、消息通知、构建安装程序

背景 自主研发了一款面向个人用户的时间管理系统&#xff0c;核心功能涵盖任务管理、番茄钟计时、日志记录等&#xff1b;该系统主要以 Web 应用形态提供给用户&#xff0c;同时配套提供微信小程序、安卓及鸿蒙端应用&#xff0c;作为时空上便利性的补充。 近期收到用户反馈&…

【AI黑科技】RAG检索增强生成,让大模型从“一本正经地胡说“到“引经据典“!

一、LLMs 已经具备了较强能力了&#xff0c;为什么还需要 RAG(检索增强生成)? 尽管 LLM 已展现出显著的能力&#xff0c;但以下几个挑战依然值得关注&#xff1a; 幻觉问题&#xff1a;LLM 采用基于统计的概率方法逐词生成文本&#xff0c;这一机制内在地导致其可能出现看似…

学霸同款2026 AI论文写作软件TOP9:自考毕业论文必备测评

学霸同款2026 AI论文写作软件TOP9&#xff1a;自考毕业论文必备测评 2026年自考论文写作工具测评&#xff1a;为何需要这份榜单&#xff1f; 随着人工智能技术的不断进步&#xff0c;AI论文写作软件已成为越来越多自考生提升效率、优化内容的重要工具。然而&#xff0c;面对市场…

书籍-沃尔特·克里斯塔勒《德国南部中心地原理》

沃尔特克里斯塔勒《德国南部中心地原理》详细介绍 书籍基本信息 书名&#xff1a;Die zentralen Orte in Sddeutschland&#xff08;德国南部中心地原理&#xff09; 作者&#xff1a;沃尔特克里斯塔勒&#xff08;Walter Christaller&#xff0c;1893-1969&#xff09;【德国地…