feign.RequestInterceptor 简介-笔记

news2025/5/13 8:06:33

1. feign.RequestInterceptor 简介

Feign 是一个声明式 Web 服务客户端,用于简化 HTTP 请求的编写与管理。feign.RequestInterceptor 是 Feign 提供的一个接口,用于在请求发出之前对其进行拦截和修改。这在微服务架构中非常有用,比如在请求中统一添加认证头、日志追踪标识、设置自定义头等,从而提升代码的可维护性和一致性。

RequestInterceptor 接口的核心方法是:

void apply(RequestTemplate template);

该方法会在每次 Feign 发起请求之前被调用。可以通过 RequestTemplate 对象修改请求的以下内容:

  • 添加或修改请求头(Headers)
  • 添加或修改请求参数(Query Parameters)
  • 修改请求体(Body)
  • 添加日志或追踪信息
  • 添加身份验证信息(如 Token、OAuth 令牌等)

2. RequestInterceptor使用示例

step1.创建 AuthRequestInterceptor。

该拦截器是一个简单的 RequestInterceptor 实现,用于在所有请求中添加认证 Token:

import feign.RequestInterceptor;
import feign.RequestTemplate;

public class AuthRequestInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        // 添加认证 Token 到请求头
        template.header("Authorization", "Bearer your_access_token_here");
    }
}

step2. 将拦截器应用到 Feign Client

通过以下两种方式将 AuthRequestInterceptor 应用到你的 Feign Client 中:

方法一:通过 @FeignClient 注解配置

import org.springframework.cloud.openfeign.FeignClient;

//注意:configuration 属性接受一个类或多个类,用于配置 Feign Client 的行为。
@FeignClient(
    name = "user-service",
    configuration = AuthRequestInterceptor.class
)
public interface UserClient {
    @GetMapping("/users/{id}")
    User getUser(@PathVariable("id") Long id);
}

方法二:通过配置类注册为 Bean

先在配置类中注册 RequestInterceptor 为 Bean:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignConfig {

    @Bean
    public RequestInterceptor authRequestInterceptor() {
        return new AuthRequestInterceptor();
    }
}

再在 @FeignClient 中引用配置类:

@FeignClient(
    name = "user-service",
    configuration = FeignConfig.class
)
public interface UserClient {
    @GetMapping("/users/{id}")
    User getUser(@PathVariable("id") Long id);
}

3. 一个完整的示例

3.1 场景说明

在微服务架构中,使用 Feign 作为 HTTP 客户端时,我们常常需要对请求进行统一处理。这些需求可以通过多个 RequestInterceptor 实现,并在 Feign 请求发送前依次执行。下面我们通过一个实际场景来演示如何配置多个 RequestInterceptor 并使用它们。

我们有一个名为 order-service 的服务,它通过 Feign 调用 user-service 来获取用户信息。在调用过程中,我们需要:

  1. 添加认证 Token(如 JWT);
  2. 生成请求追踪 ID(用于链路追踪);
  3. 记录请求日志(便于调试与监控)。

3.2 项目结构

src/main/java
├── config
│   └── FeignConfig.java
├── interceptor
│   ├── AuthInterceptor.java
│   ├── TraceInterceptor.java
│   └── LoggingInterceptor.java
├── client
│   └── UserClient.java
└── Application.java

3.3 代码

step1. 定义多个 RequestInterceptor

AuthInterceptor: 添加认证信息

package com.example.interceptor;

import feign.RequestInterceptor;
import feign.RequestTemplate;

public class AuthInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        template.header("Authorization", "Bearer your_access_token");
    }
}

TraceInterceptor: 添加请求追踪 ID

package com.example.interceptor;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import java.util.UUID;

public class TraceInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        String traceId = UUID.randomUUID().toString();
        template.header("X-Request-ID", traceId);
    }
}

LoggingInterceptor:记录请求日志

// LoggingInterceptor.java
package com.example.interceptor;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LoggingInterceptor implements RequestInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);

    @Override
    public void apply(RequestTemplate template) {
        logger.info("Sending request to: {}", template.url());
        logger.info("Method: {}, Headers: {}", template.method(), template.headers());
    }
}

step2.配置多个 RequestInterceptor

将多个拦截器注册为 Bean,并统一配置到 Feign Client 中:

package com.example.config;

import com.example.interceptor.AuthInterceptor;
import com.example.interceptor.LogginInterceptor;
import com.example.interceptor.TraceInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignConfig {

    @Bean
    public AuthInterceptor authInterceptor() {
        return new AuthInterceptor();
    }

    @Bean
    public TraceInterceptor traceInterceptor() {
        return new TraceInterceptor();
    }

    @Bean
    public LogginInterceptor loggingInterceptor() {
        return new LogginInterceptor();
    }
}

⚠️ 注意:Spring Boot 会自动将所有 RequestInterceptor 类型的 Bean 注册到 Feign 中,无需手动注入,只要 Feign Client 使用了对应的配置。

step3. Feign Client 使用配置

package com.example.client;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(
    name = "user-service",
    configuration = FeignConfig.class // 关键:引用配置类
)
public interface UserClient {

    @GetMapping("/users/{id}")
    String getUserById(@PathVariable("id") Long id);
}

当调用 userClient.getUserById(123) 时,控制台输出如下:

INFO  LoggingInterceptor - Sending request to: http://user-service/users/123
INFO  LoggingInterceptor - Method: GET, Headers: {Authorization=[Bearer your_access_token], X-Request-ID=[abc123...]}

拦截器执行顺序说明

Feign 默认按照 Bean 注册顺序执行 RequestInterceptor。你可以通过 @Order 注解改变执行顺序,例如:

@Order(1)
public class AuthInterceptor implements RequestInterceptor { ... }


@Order(2)
public class TraceInterceptor implements RequestInterceptor { ... }

3.4 其他用法

3.4.1 可以不使用@FeignClient 配置的做法

也可以将 FeignConfig 类集成到 Spring Boot 的自动配置类中,并通过 spring.factories 注册该自动配置类时

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.client. FeignConfig

这样就无需在 @FeignClient 中通过 configuration = FeignConfig.class 显式引用配置类。

原因:

  1. 自动配置机制的作用:Spring Boot 的自动配置机制通过 spring.factories 文件注册的类在应用启动时自动加载。只要 FeignConfig 正确地注册了 RequestInterceptor 等 Bean(如 AuthInterceptorTraceInterceptorLoggingInterceptor),这些 Bean 就会被 Spring 容器管理,并且 全局生效

  2. FeignClient 的默认行为:Feign Client 在创建时会自动查找 Spring 容器中所有 RequestInterceptor 类型的 Bean,并按照注册顺序依次应用。因此,只要这些拦截器被正确注册为 Spring Bean,就不需要通过 @FeignClient(configuration = ...) 引用配置类。        

3.4.2 何时仍需使用@FeignClient 配置

虽然大多数情况下不需要显式引用配置类,但在以下场景中仍可能需要使用 @FeignClient(configuration = FeignConfig.class)

  1. 自定义 Feign Client 的配置需求

    • 如果某个 Feign Client 需要使用特定的配置类(比如不同的拦截器组合或覆盖默认配置),可以通过 configuration 属性指定。
    • 例如,某个 Feign Client 只需要 AuthInterceptor,而其他 Feign Client 需要 AuthInterceptor + LoggingInterceptor
  2. 控制 Bean 加载顺序

    • 如果拦截器的执行顺序非常重要,可以通过 @Order 注解或在配置类中显式控制顺序。
    • 使用 @FeignClient(configuration = FeignConfig.class) 可以确保配置类中的 Bean 被优先加载。
  3. 避免自动配置与手动配置冲突

    • 如果自动配置类和手动配置类中存在相同类型的 Bean(如多个 RequestInterceptor 实现),可能会导致冲突。此时可通过 @FeignClient(configuration = ...) 显式指定。

3.4.3 总结

场景是否需要 @FeignClient(configuration = FeignConfig.class)
FeignConfig 已通过自动配置类注册到 Spring 容器❌ 不需要
某个 Feign Client 需要自定义拦截器组合✅ 需要
需要控制拦截器的执行顺序✅ 需要(结合 @Order 使用)
避免自动配置与手动配置冲突✅ 需要

实践建议

  • 优先使用自动配置:如果所有 Feign Client 都需要相同的拦截器配置,直接通过自动配置类注册即可,无需每个 Feign Client 配置 configuration
  • 确保自动配置类正确注册:检查 FeignConfig 是否已注册到 Spring 容器,并验证拦截器是否生效。
  • 按需定制配置:如果某些 Feign Client 需要特殊处理,再通过 @FeignClient(configuration = ...) 显式指定。

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

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

相关文章

vLLM中paged attention算子分析

简要分析vLLM中PA的代码架构和v1与v2的区别 vLLM版本:0.8.4 整体结构分析 首先从torch_bindings.cpp入手分析: 这里可以看到vLLM向pytorch中注册了两个PA算子:v1和v2 其中paged_attention_v1和paged_attention_v2分别实现在csrc/attentio…

多样本整合Banksy空间聚类分析(Visium HD, Xenium, CosMx)

在空间数据分析中,传统的单细胞聚类算法,例如Seurat和Scanpy中的lovain和leiden等聚类算法,通常在处理空间数据时忽略了空间信息。然而,由于细胞状态受其周围细胞的影响,将转录组数据与细胞的空间信息结合起来进行聚类…

使用 OAuth 2.0 保护 REST API

使用 OAuth 2.0 保护 REST API 使用 OAuth 2.0 保护 REST API1.1 不安全的api1.2 安全默认值安全默认值Spring Security 默认值 需要对所有请求进行身份验证Servlet、过滤器和调度程序安全优势 使用所有请求的安全标头进行响应缓存标头 严格传输安全标头内容类型选项需要对所有…

解决下拉框数据提交后回显名称不对

问题背景描述 页面组件使用 antd 的 Select 组件,下拉框的 options 数据是动态获取的,基本就是有value 和 label 属性的对象数组。 提交数据后,我们有一个保存草稿的操作,支持返回或者刷新页面,浏览其他页面之后通过其…

lenis滑动插件的笔记

官网 lenis - npm 方法一:基础判断(推荐) 通过 Lenis 自带的 scroll 和 limit 属性直接判断: const lenis new Lenis()// 滚动事件监听 lenis.on(scroll, ({ scroll, limit }) > {const distanceToBottom limit - scroll…

Android Framework

Android 分区 /boot:存放引导程序,包括内核和内存操作程序。/system:相当于电脑 C 盘,存放 Android 系统及系统应用。/recovery:恢复分区,可以进入该分区进行系统恢复。/data:用户数据区&#…

OpenMCU(六):STM32F103开发板功能介绍

概述 距上一篇关于STM32F103的FreeRTOS博客的发布已经过去很长时间没有更新了。在这段时间内,大家可以看到博主发表了一系列的关于使用qemu 模拟实现STM32F103的博客,博主本来想借助qemu开发stm32F103相关的一些软件功能,博主开发出来并成功运…

Rspack:字节跳动自研 Web 构建工具-基于 Rust打造高性能前端工具链

字节跳动开源了一款采用 Rust 开发的前端模块打包工具:Rspack(读音为 /ɑrspk/)。 据介绍,Rspack 是一个基于 Rust 的高性能构建引擎,具备与 Webpack 生态系统的互操作性,可以被 Webpack 项目低成本集成&a…

高速系统设计实例设计分析

在上几章的内容中,我们从纯粹高速信号的理论分析,到 Cadence 工具的具体使用都做了详细的讲解和介绍。相信读者通过前面章节的学习,已经对高速系统的设计理念及 Cadence 相应的设计流程和工具有了一个基本的认识。但是,对于高速电…

查看购物车

一.查看购物车 查看购物车使用get请求。我们要查看当前用户的购物车,就要获取当前用户的userId字段进行条件查询。因为在用户登录时就已经将userId封装在token中了,因此我们只需要解析token获取userId即可,不需要前端再传入参数了。 Control…

开发工具分享: Web前端编码常用的在线编译器

1.OneCompiler 工具网址:https://onecompiler.com/ OneCompiler支持60多种编程语言,在全球有超过1280万用户,让开发者可以轻易实现代码的编写、运行和共享。 OneCompiler的线上调试功能完全免费,对编程语言的覆盖也很全&#x…

智启未来:新一代云MSP管理服务助力企业实现云成本管理和持续优化

在数字化转型浪潮下,企业纷纷寻求更高效、更经济的运营方式。随着云计算技术的深入应用,云成本优化已成为企业普遍关注的核心议题。 过去,传统云运维服务往往依赖于人力外包,缺乏系统性、规范性的管理,难以有效降低云…

window 显示驱动开发-将虚拟地址映射到内存段(二)

在将虚拟地址映射到段的一部分之前,视频内存管理器调用显示微型端口驱动程序的 DxgkDdiAcquireSwizzlingRange 函数,以便驱动程序可以设置用于访问可能重排的分配位的光圈。 驱动程序既不能将偏移量更改为访问分配的 PCI 光圈,也不能更改分配…

【文心智能体】使用文心一言来给智能体设计一段稳定调用工作流的提示词

🌹欢迎来到《小5讲堂》🌹 🌹这是《文心智能体》系列文章,每篇文章将以博主理解的角度展开讲解。🌹 🌹温馨提示:博主能力有限,理解水平有限,若有不对之处望指正&#xff0…

K8S中构建双架构镜像-从零到成功

背景介绍 公司一个客户的项目使用的全信创的环境,服务器采用arm64的机器,而我们的应用全部是amd64的,于是需要对现在公司流水线进行arm64版本的同步镜像生成。本文介绍从最开始到最终生成双架构的全部过程,以及其中使用的相关配置…

c语言第一个小游戏:贪吃蛇小游戏03

我们为贪吃蛇的节点设置为一个结构体,构成贪吃蛇的身子的话我们使用链表,链表的每一个节点是一个结构体 显示贪吃蛇身子的一个节点 我们这边node就表示一个蛇的身体 就是一小节 输出结果如下 显示贪吃蛇完整身子 效果如下 代码实现 这个hasSnakeNode(…

​​​​​​​大规模预训练范式(Large-scale Pre-training)

大规模预训练指在巨量无标注数据上,通过自监督学习训练大参数量的基础模型,使其具备通用的表征与推理能力。其重要作用如下: 一 跨任务泛化 单一模型可在微调后处理多种NLP(自然语言处理)、CV(计算机视觉…

WPF之高级绑定技术

文章目录 引言多重绑定(MultiBinding)基本概念实现自定义IMultiValueConverterMultiBinding在XAML中的应用示例使用StringFormat简化MultiBinding 优先级绑定(PriorityBinding)基本概念PriorityBinding示例实现PriorityBinding的后…

调出事件查看器界面的4种方法

方法1. 方法2. 方法3. 方法4.

使用vite重构vue-cli的vue3项目

一、修改依赖 首先修改 package.json,修改启动方式与相应依赖 移除vue-cli并下载vite相关依赖,注意一些peerDependency如fast-glob需要手动下载 # 移除 vue-cli 相关依赖 npm remove vue/cli-plugin-babel vue/cli-plugin-eslint vue/cli-plugin-rout…