# 04.微服务-openFeign

# 1.介绍

# 1.1 什么是 OpenFeign?

OpenFeign 是一个声明式的 HTTP 客户端框架,最初由 Netflix 开发,后成为 Spring Cloud 生态的核心组件

核心理念:通过接口 + 注解的方式定义远程服务调用,将底层 HTTP 通信细节交给框架处理,开发者只需关注"做什么",而非"如何做"

# 1.2 Feign vs OpenFeign

对比项 Feign OpenFeign
注解支持 仅支持 Feign 原生注解 支持 Spring MVC 注解(@RequestMapping@GetMapping 等)
框架集成 独立组件 深度集成 Spring Cloud,支持 Ribbon 负载均衡、服务发现等

📌 选型建议:Spring Cloud 项目中直接使用 OpenFeign。

# 1.3 核心注解

① @FeignClient:标注在接口上,声明这是一个 Feign 客户端。

属性 说明 示例
name / value 目标服务名(注册中心中的服务 ID),配合 Ribbon 实现负载均衡 @FeignClient(name = "order-service")
url 直接指定服务 URL(用于调试或非注册中心场景) @FeignClient(url = "http://localhost:8081")
path 统一请求前缀 @FeignClient(path = "/api/v1")
configuration 指定该客户端的专用配置类 @FeignClient(configuration = FooConfig.class)
fallback 熔断降级类(需实现该接口) @FeignClient(fallback = MyFallback.class)
fallbackFactory 熔断工厂类,可获取异常原因 @FeignClient(fallbackFactory = MyFactory.class)

② @EnableFeignClients:标注在启动类上,开启 Feign 客户端扫描和代理生成

# 2.快速使用

# 2.1引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
1
2
3
4

# 2.2启动类开启Feign

@SpringBootApplication
@EnableFeignClients   // 开启 Feign 客户端
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
1
2
3
4
5
6
7

# 2.3定义Feign接口

@Component
@FeignClient(value = "stock-service",path = "/stock")
public interface StockFeignService {
    @RequestMapping("/deduct")
    String deduct();
}
1
2
3
4
5
6

# 2.4使用

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private StockFeignService stockFeignService;

    @RequestMapping("/add")
    public String add(){
        System.out.println("下单成功");
        String msg = stockFeignService.deduct();
        return "hello feign"+msg;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 2.5 参数传递方式

场景 注解 示例
URL 路径参数 @PathVariable @GetMapping("/{id}") @PathVariable Long id
JSON 请求体 @RequestBody @PostMapping("/create") @RequestBody Order order
表单/Query 参数 @SpringQueryMap @GetMapping("/search") @SpringQueryMap Params params

# 3.日志配置

# 3.1 日志级别

级别 记录内容
NONE 不记录任何日志(默认
BASIC 请求方法、URL、响应状态码、执行时间
HEADERS BASIC + 请求和响应的 Header 信息
FULL HEADERS + 请求和响应的 Body 及元数据

# 3.2 配置方式

先设置springboot的日志级别(默认是info),info情况下feign的debug日志级别不会输入

logging:
  level:
    # 格式:包名.接口名: DEBUG
    com.xy.order.feign.StockFeignService: DEBUG
1
2
3
4

方式一:Java Config(推荐)

@Configuration
public class FeignLogConfig {

    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;   // 设置为 FULL 级别
    }
}
1
2
3
4
5
6
7
8

@FeignClient注解中配置设置好的日志级别

@FeignClient(value = "stock-service",path = "/stock",configuration = FeignLogConfig.class)
1

方式二:配置文件 application.yml

spring:
  application:
    name: order-service
  cloud:
    openfeign:
      client:
        config:
          stock-service:
            logger-level: full
1
2
3
4
5
6
7
8
9

# 3.3 全局 vs 局部配置

  • 全局生效:配置类使用 @Configuration 注解,被组件扫描到

  • 仅对指定服务生效:配置类不加 @Configuration,通过 @FeignClient(configuration = FeignLogConfig.class) 指定

⚠️ 注意:日志级别需配合 logging.level.接口路径: DEBUG 才会实际输出

# 4.超时时间

# 4.1 核心参数

参数 含义 默认值
connectTimeout 建立连接的超时时间(毫秒) 10 秒
readTimeout 读取数据的超时时间(毫秒) 60 秒

# 4.2 配置方式

方式一:配置文件(推荐)

spring:
  application:
    name: order-service
  cloud:
    openfeign:
      client:
        config:
          stock-service:
            logger-level: full
            connect-timeout: 3000
            read-timeout: 5000
1
2
3
4
5
6
7
8
9
10
11

方式二:Java Config

@Configuration
public class TimeoutConfig {

    @Bean
    public Request.Options options() {
        // 连接超时 1 秒,读取超时 3 秒
        return new Request.Options(1000, 3000);
    }
}
1
2
3
4
5
6
7
8
9

# 5.自定义拦截器

# 5.1 核心接口

实现 RequestInterceptor 接口,重写 apply(RequestTemplate template) 方法

原理:Spring 容器自动扫描所有 RequestInterceptor Bean,在每次 Feign 请求发出前调用其 apply 方法,向 RequestTemplate 注入 Header 或其他参数

# 5.2 典型应用场景

场景 说明
认证透传 将 JWT / OAuth2 Token 自动传递到下游服务
链路追踪 自动生成并传递 TraceId / SpanId
灰度标记 携带 X-Env: gray 等标识实现灰度路由
多语言/本地化 自动传递 Accept-Language

# 5.3 代码示例

① 创建拦截器类

@Component
public class FeignAuthInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        // 从 ThreadLocal / SecurityContext 获取 Token
        String token = UserContextHolder.getToken();
        if (StringUtils.hasText(token)) {
            template.header("Authorization", "Bearer " + token);
        }

        // 传递链路追踪 ID(可选)
        String traceId = MDC.get("traceId");
        if (traceId != null) {
            template.header("X-Trace-Id", traceId);
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 5.4 注册拦截器

将拦截器声明为 Spring Bean 即可自动生效

@Configuration
public class FeignInterceptorConfig {

    @Bean
    public RequestInterceptor getRequestInterceptor() {
        return new FeignAuthInterceptor();  // 或 new FeignRequestInterceptor()
    }
}
1
2
3
4
5
6
7
8

over

最近更新: 9/19/2026, 1:27:08 PM
编程NOTE   |