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

feign.RequestInterceptor 简介-笔记

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 {@Overridepublic 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 {@Beanpublic 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 {@Overridepublic 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 {@Overridepublic 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);@Overridepublic 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 {@Beanpublic AuthInterceptor authInterceptor() {return new AuthInterceptor();}@Beanpublic TraceInterceptor traceInterceptor() {return new TraceInterceptor();}@Beanpublic 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 = ...) 显式指定。

相关文章:

  • 为什么 mac os .bashrc 没有自动加载?
  • 【c++】异常详解
  • 2.1 微积分基本想法
  • Linux操作系统安全加固
  • Maven私服搭建与登录全攻略
  • Qt进阶开发:QTcpServer的的详解
  • [高阶数据结构]二叉树经典面试题
  • 蚁群算法赋能生鲜配送:MATLAB 实现多约束路径优化
  • Vue:插值表达
  • pytorch模型画质增强简单实现
  • 关系型数据库和非关系型数据库
  • 一次IPA被破解后的教训(附Ipa Guard等混淆工具实测)
  • rust 全栈应用框架dioxus server
  • AI大模型学习十九、利用Dify+deepseekR1 使用文件上传搭建文章理解助手
  • FastMCP v2:构建MCP服务器和客户端的Python利器
  • java 中 DTO 和 VO 的核心区别
  • 一键解锁嵌入式UI开发——LVGL的“万能配方”
  • ASP.NET Core Identity框架使用指南
  • 如何使用 React Hooks 替代类组件的生命周期方法?
  • 【AI大语言模型本质分析框架】
  • 在地球另一端的交流,架起2万公里间更多共赢的桥梁
  • 社恐也能嗨起来,《孤独摇滚》千人观影齐舞荧光棒
  • 巴基斯坦总理:希望通过和平对话方式解决与印方问题
  • 国办印发《关于进一步加强困境儿童福利保障工作的意见》
  • 优秀“博主”在上海杨浦购房最高补贴200万元,有何条件?
  • 洲际酒店:今年第一季度全球酒店平均客房收入同比增长3.3%